【问题标题】: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 为该算法制作可视化。
  • 您需要具体说明您的算法应该做什么。话虽如此,如果可能,您应该将排序逻辑与其他逻辑分开(除非它是排序算法的一部分)。
  • @DanielCalota 如果你转到我在 cmets 中的 stackoverflow 链接,最重要的是摆脱这个测试:*itj &gt; *leftmost,而是调用一个返回 true 或 @ 的函数987654327@ 取决于左侧值是否放在右侧值之前。在该函数中,除了返回值之外,您还可以执行任何其他操作。此外,那个 geeksforgeeks 网站——不要从那里获取代码示例,因为它们中的大多数都很糟糕。

标签: c++ stl iterator


【解决方案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 STL1implementation

    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++中找到。

    【讨论】:

      猜你喜欢
      • 2019-05-12
      • 1970-01-01
      • 2012-01-05
      • 2019-01-06
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多