使用迭代器和向量的插入排序实现
Posted
技术标签:
【中文标题】使用迭代器和向量的插入排序实现【英文标题】:Insertion sort implementation using iterators and vectors 【发布时间】:2020-08-01 14:42:15 【问题描述】:我正在尝试使用迭代器来实现插入排序算法,但它似乎并没有像我想象的那样工作......你对如何实现它有任何想法吗?
另外,我不能使用像这样的代码:https://www.geeksforgeeks.org/insertion-sort-using-c-stl/,因为我打算制作一个动画,它会变得更复杂。
这是我目前的源代码:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
std::vector<int> seq = 5, 4, 3, 2, 1 ;
std::vector<int>::iterator itj;
std::vector<int>::iterator leftmost;
// insertion sort
for (std::vector<int>::iterator iti = seq.begin() + 1; iti != seq.end(); iti = std::next(iti))
itj = std::prev(iti);
leftmost = iti;
while (std::distance(seq.begin(), itj) >= 0 && *itj > *leftmost)
std::next(itj) = itj;
itj = prev(itj);
std::next(itj) = leftmost;
// printing
for (std::vector<int>::iterator iti = seq.begin(); iti != seq.end(); iti = std::next(iti))
std::cout << *iti << " ";
【问题讨论】:
糟糕,我刚刚意识到您分享的链接有一个使用rotate
的实现。你能解释一下为什么这对你的情况不起作用。你想要一个以某种方式扩展插入排序的算法吗?
是的,有点……所以目前,我正在尝试使用 sfml 为该算法制作可视化。
A much better discussion on sorting algorithms.
您需要具体说明您的算法应该做什么。话虽如此,如果可能,您应该将排序逻辑与其他逻辑分开(除非它是排序算法的一部分)。
@DanielCalota 如果你转到我在 cmets 中的 *** 链接,最重要的是摆脱这个测试:*itj > *leftmost
,而是调用一个返回 true
或 @ 的函数987654327@ 取决于左侧值是否放在右侧值之前。在该函数中,除了返回值之外,您还可以执行任何其他操作。此外,那个 geeksforgeeks 网站——不要从那里获取代码示例,因为它们中的大多数都很糟糕。
【参考方案1】:
这是一个非常优雅的插入排序实现,它使用直接从rotate 上的参考页面提取的迭代器:
// insertion sort
for (auto i = v.begin(); i != v.end(); ++i)
std::rotate(std::upper_bound(v.begin(), i, *i), i, i+1);
您所要做的就是了解std::rotate
的工作原理,这将变得很容易理解。 (无论如何,rotate
是一个非常强大的算法,您应该对此感到满意)。
【讨论】:
【参考方案2】:这是取自 SGI STL1 的implementation:
template<class Random_it, class T>
void unguarded_linear_insert(Random_it last, T val)
auto next = last;
--next;
while (val < *next)
*last = *next;
last = next;
--next;
*last = val;
template<class Random_it>
void linear_insert(Random_it first, Random_it last)
auto val = *last;
if (val < *first)
std::copy_backward(first, last, last + 1);
*first = val;
else
unguarded_linear_insert(last, val);
template<class Random_it>
void insertion_sort(Random_it first, Random_it last)
if (first == last)
return;
for (auto i = first + 1; i != last; ++i)
linear_insert(first, i);
注意val < *first
条件和std::copy_backward
如何用于简化unguarded_linear_insert
内的循环:只有一个 条件,即val < *next
可以在该循环中检查。
1同样的implementation可以在libstdc++中找到。
【讨论】:
以上是关于使用迭代器和向量的插入排序实现的主要内容,如果未能解决你的问题,请参考以下文章