简单排序算法的时间下界

插入排序

插入排序是最简单的排序算法之一,对于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)。

这个下界告诉我们,为了以亚二次时间运行,必须要对相距较远的元素进行交换,这样的一次交换可能会消除多个逆序。

转载请注明出处:喻红叶《排序算法的时间下界》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值