使用迭代器和向量的插入排序实现

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 &gt; *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 &lt; *first 条件和std::copy_backward 如何用于简化unguarded_linear_insert 内的循环:只有一个 条件,即val &lt; *next 可以在该循环中检查。

1同样的implementation可以在libstdc++中找到。

【讨论】:

以上是关于使用迭代器和向量的插入排序实现的主要内容,如果未能解决你的问题,请参考以下文章

jdk8源码Arrays.sort插入排序

排序(选择插入希尔)

将元素插入已排序的向量中

插入排序

对链表进行插入排序

279,对链表进行插入排序