插入排序
插入排序是最简单的排序算法之一,对于N个元素的序列,需要进行N-1次的插入来完成排序。插入排序的算法:
(1)对于位置P,0到P-1位置上的元素已经是有序的,P从1开始;
(2)将P指向的元素放到[0,P]正确的位置,这样0到P位置上的元素也是有序的。
插入排序确实很简单,不需要过多的介绍,直接用一个示例来演示其过程,待排序列:2 4 6 1 3 5 总共有6个元素,所以需要5趟排序,P从1开始
(1)2是一个有序序列
(2)P=1,将4插入到正确位置,排序后:2 4
(3)P=2,将6插入到正确位置,排序后:2 4 6
(4)P=3,将1插入到正确位置,排序后:1 2 4 6
(5)P=4,将3插入到正确位置,排序后:1 2 3 4 6
(6)P=5,将5插入到正确位置,排序后:1 2 3 4 5 6
插入排序代码:
void insertsort(int *A,int n) {
int i,j;
int x;
for(i = 1; i < n; i++) {
x = A[i];//待插入元素
for(j = i; j > 0 && A[j - 1] > x; --j)
A[j] = A[j - 1];
A[j] = x;
}
}
上面的代码实现是比较好的,它移动实现了元素移动,却没有明显的使用交换,而是使用x保存待插入元素,不断将x之前的元素往右移动,直到空出适合x插入的位置。
时间复杂度分析
对于P每一个值,代码中第6行的内层for循环最多执行P+1次比较,对所有的P求和:
T(N) = 2 + 3 + 4 + .... + N = O(N^2) = o(N^2)
如果输入是有序的,那么内层for循环就不会执行,因此时间复杂度是O(N),这是最好的情形。平均时间复杂度是:O(N^2) = o(N^2)
简单排序的时间下界
数组的一个逆序:数组中i < j,但A[i] > A[j]的序偶(A[i],A[j])。
在上面的序列中存在(2,1),(4,1),(4,3),(6,1),(6,3),(6,5)这6个逆序。想一下插入排序的过程,如果待插入元素与前面的元素存在逆序,那么就需要交换数据,每次都是和相邻的元素交换,交换一次只能消除一个逆序。也就是说数组中的逆序个数就是排序时的交换次数。 插入排序时,除了交换外还有其他O(N) 项工作,设I为原数组中的逆序数,因此插入排序的时间复杂度是O(I + N)。如果能求出I的平均值,也就求出了插入排序的平均时间复杂度。
定理:N个互异的数组的平均逆序数是N(N - 1) / 4。
证明:对于任意序列L,其反序是~L,对于L中的任意两个数(x,y),且y > x。如果x在y的前面,那么对于~L而言,x就在y的后面,(x,y)就是~L的逆序:
L:..... x ...... y ......
~L:....... y ....... x .......
反之,如果x在y的后面,(x,y)就是L的逆序。总之,对于任意(x,y),它要么是L的逆序,要么是~L的逆序。这样L + ~L的逆序总和是:C(N,2) = N(N - 1) / 2。L的平均逆序就应该是总量的一半:N(N-1) / 4。
序列的平均逆序数是二次的,交换相邻元素只能消除一个逆序。因此,凡是通过只交换相邻元素的排序算法的平均时间是二次的,这是这类算法一个很强的下界。因此我们又得到一个定理:通过交换相邻元素进行排序的任何算法平均需要Ω(N^2)。
这个下界告诉我们,为了以亚二次时间运行,必须要对相距较远的元素进行交换,这样的一次交换可能会消除多个逆序。
转载请注明出处:喻红叶《排序算法的时间下界》
分享到:
相关推荐
上传时间:2020/11/09 最后测试:2020/11/09 内容:排序算法的下界和如何超越下界原理及实现 其他:pytorch学习练习代码 相关介绍:https://blog.csdn.net/jerry_liufeng/article/details/109587637
首先, let's 看一下这些排序算法的时间复杂度和空间复杂度: | 排序算法 | 平均情况 | 最好情况 | 最坏情况 | 辅助空间 | 稳定性 | | --- | --- | --- | --- | --- | --- | | 冒泡排序 | O(n^2) | O(n) | O(n^2) |...
十大经典排序算法 编程界里面比较公认的十大经典排序算法可以分为两⼤类: ⽐较类排序:通过⽐较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为⾮线性时间⽐较类排序。 ⾮⽐较类排序:不...
基于比较的排序算法: 下界是 nlgn 1.1 SelectionSort:每次选出最下的元素,放在当前循环最左边的位置。 1.2 BubbleSort:每次比较相邻的两个数,使得最大的数像气泡一样冒到最右边。 1. 3 InsertionSort:每次拿起...
八大排序算法的比较可以从时间复杂度、空间复杂度和稳定性三个方面进行比较,其中选择排序和冒泡排序的时间复杂度都是 O(n^2),空间复杂度都是 O(1);插入排序的时间复杂度是 O(n^2),空间复杂度是 O(1);归并排序和...
接着,PPT讨论了简单排序算法的下界。逆序是对数组中元素顺序的一种衡量,两个不按原序排列的相邻元素构成一个逆序。在插入排序中,每消除一个逆序就需要进行一次元素交换。平均情况下,N个互异数的数组的逆序数为N...
**(基于比较的)排序算法时间的下界**: - 对于基于比较的排序算法,其时间复杂度的下界为Ω(n log n)。这是因为基于比较的排序算法必须通过比较来确定元素之间的相对顺序,而比较的结果构成了一棵决策树,这棵树的...
通过构建决策树来分析比较过程,可以得出在最坏情况下,任何排序算法的时间复杂性下界为Ω(nlogn)。这是因为即使是最高效的比较排序算法,其时间复杂度也无法低于这个界限。 接下来,我们详细讨论了几种基本排序...
如插入排序(直接插入排序,折半插入排序,希尔排序)、交换排序(冒泡排序,快速排序)、选择排序(简单选择排序,堆排序)、2-路归并排序(可以参考前一篇文章:各种内部排序算法的实现)等,这些排序算法都有一个...
简单选择排序的时间复杂度同样为 O(n^2),但与其他O(n^2)的排序算法相比,它在交换操作上较少,因此在某些情况下可能更高效。 以上介绍了三种排序算法的基本思想、示例代码及性能分析。后续还将详细介绍剩余五种...
虽然基于比较的排序算法的最坏情况时间复杂度下限为Ω(n log n),但在某些特殊情况下,我们可以使用线性时间排序算法,其时间复杂度为O(n)。 **1. 计数排序(Counting Sort)** 计数排序适用于输入范围较小的情况...
要求能够手写时间复杂度位O(nlogn)的排序算法:快速排序、归并排序、堆排序 1.冒泡排序 思想:相邻的两个数字进行比较,大的向下沉,最后一个元素是最大的。列表右边先有序。 时间复杂度$O(n^2)$,原地排序,稳定的...
它通过构建一棵树形结构来表示所有可能的比较序列及其结果,从而推导出任何基于比较的排序算法的时间复杂度下限。 **决策树节点**: - 内部节点代表一次元素之间的比较操作。 - 叶子节点代表一个具体的排序结果。 ...
通过计算决策树的高度,我们得出了比较排序算法下界——Ω(nlgn),即任何基于比较的排序算法在最坏情况下至少需要进行这么多次比较。这一理论为我们指明了优化排序算法的极限所在。 接下来,我们重点讲解了计数排序...
这些习题可能会讨论比较排序算法的下界,即任何基于比较的排序算法至少需要进行多少次比较才能完成排序。 #### 9.2-1 至 9.3-9 这部分内容可能更深入地探讨了排序问题的理论极限,以及如何证明某些排序算法的最优...
快速排序(Quick Sort)是一种高效的排序算法,具有良好的时间复杂度和空间复杂度。快速排序的实现基于分治法,具体分为三个步骤:分解、解决和合并。 在分解步骤中,序列被划分成两个可能为空的子序列,左边的子...
这表明任何基于比较的排序算法的最坏情况下的时间复杂度至少为Ω(n log n)。 ### 第3章 - 增长阶函数 #### 3.1 渐进记号 - **3.1-1**:定义并理解大O、小o、θ、Ω和ω记号。 - **3.1-2**:比较不同渐进记号之间...
"算法分析与设计期末考试试卷" ...以上是算法分析与设计期末考试试卷的主要知识点,涵盖了算法的时间复杂性、分治算法、动态规划、贪心算法、PQ 式的分支限界法、随机算法、快速排序算法、SPLIT 算法等。