-->

运行时间插入排序(Running Time For Insertion Sort)

2019-08-08 02:29发布

for (int p=1; p < a.size(); p++) {
    int tmp = a[p];
    for(j=p; j>0 && tmp < a[j-1]; j--) {
        a[j] = a[j-1];
    }
    a[j] = tmp;
}

我无法找出对插入排序的最坏情况。 因此,考虑到数组按降序排列,我们希望它在升序排列。

外环穿过阵列。 所以,它运行(n次)。 为O(n) int tmp=a[p] ----该语句被执行n次。 为O(n)的内部循环得到执行(1 + 2 + 3 + 4 + 5 + 6 + .... + N-1)次。 为O(n ^ 2) a[j]= tmp --------此语句得到执行n次。 上)

我不知道以后做找到插入排序的运行时间是什么? 如果你可以纠正我的工作。 谢谢。

Answer 1:

下面是两行通用的C ++ 11实现插入排序的

template< typename ForwardIterator, typename Compare = std::less<typename std::iterator_traits<ForwardIterator>::value_type> >
void insertion_sort(ForwardIterator first, ForwardIterator last, Compare cmp = Compare())
{
        for (auto it = first; it != last; ++it) {
                auto const insertion = std::upper_bound(first, it, *it, cmp);
                std::rotate(insertion, it, std::next(it));
        }
}

该算法需要一个范围内的元素(由两个迭代给定的firstlast和比较功能(其默认为可能内建) operator<对于元件所指向的)。

主循环(以元素的数量线性)保持子区间[first, it)排序,并重复搜索的哪里放置下一个元件的插入点。 这相当于给你的主循环。 它这样做有一个二进制搜索 (对数的复杂性)。 在你的代码使用反向线性搜索(至极具有线性复杂,但有可能更好的缓存行为)。

它已找到插入点之后,它简单地旋转两个范围[insertion, it)[it, it+1)这意味着当前元素交换到插入点。 这种旋转是在迄今已分类的元素数呈线性关系。 既然是嵌套在主循环中,插入排序的整体复杂性是二次,ie.e. O(N^2) 您的代码集成交换和搜索插入点,但不改变的复杂性。

请注意,当输入电压范围已经排序,插入点永远是等于元素指向it ,这意味着该std::rotate不必在所有交换任何东西。 足够聪明,优化编译器应该能够执行优化。 如果是这样的情况下,在一个有序区间插入排序具有线性复杂性。

类似的2线的方法来选择排序给出这里 。



Answer 2:

外循环执行n次。

内循环的每次运行执行某处0且p-1之间的时间,其中p从0变化到n。 在最坏的情况下,将执行P-1倍。 如果p为0至n,则平均来说,p为N / 2。 所以,用于内循环的最坏情况下的复杂度为O(P-1)= O(N / 2-1)= O(N)。

除了循环,代码是所有O(1)(大部分重要的是,内环内的代码),所以才说事拉环。

为O(n)*为O(n)= O(N ^ 2)。

QED。

这大约是你自己给了分析。



文章来源: Running Time For Insertion Sort