排序算法(一)—插入排序(Insertion sort)

来源:互联网 发布:知乎怎么移除粉丝 编辑:程序博客网 时间:2024/04/29 21:50

插入排序是排序算法中比较简单的算法,此算法的最坏时间复杂度是O(n^2),算是比较慢的算法了,其优点是空间上是in place的,只需要占用常量的额外存储空间。

算法的python代码如下:

def insertionSort(A):    for j in range(len(A)):        key = A[j]        i = j-1        while i > -1 and key < A[i]:            A[i+1] = A[i]            i = i - 1        A[i+1] = key    return A
《算法导论》中关于该算法的时间复杂度计算过程如下:


从该分析过程来看,当待排序的序列为倒序时,算法第5、6、7行的执行次数是O(n^2),因此根据算法渐近分析的规则,算法的复杂度是O(n^2)。而当序列接近正序时,第5行每次循环指执行1次,6、7行不执行,因此此时算法的复杂度是O(n)。

以前曾粗略的认为算法有两层循环,因此算法的最坏时间复杂度是O(n^2),但是经过仔细分析发现不是这么回事,是5、6、7行导致的O(n^2)。所以在分析算法的时候也应该按照书中这样,把每一步的cost和times都搞清,然后求和。

另外当待排序的序列以不同的形式存储时导致O(n^2)的原因也不同,当序列是数组形式存储时,我们可以用二分查找来寻找key的合适插入位置,因此比较的过程缩短到O(nlogn),然而移动元素的过程仍然是O(n^2),因此渐近分析的结果不变,只是提高了渐近分析中被隐藏的常数。而当序列以链表形式存储时,插入的过程的复杂度变为O(1),然而比较的过程仍然是O(n^2)。因此可以看出当用两种数据结构存储序列时,造成算法复杂度的原因不同。

另外还有一种插入排序,就是把排序好的序列存为其他的数据结构,如2-3-4树、或者splay 树,这样算法的复杂度会降到O(nlogn),不过这样算法就不是in place的了,并且渐近分析隐藏的常数也比较大,因此在说插入排序时,通常不是指这种排序。

本文要点:

(1) 算法分析时不能想当然,要严格按照分析每一步的cost与times进行。

(2)当序列以数组的形式存储时,可以采用二分查找来优化查找过程,但是插入过程的复杂度不变。

(3)用链表形式存储与用数组形式存储的最坏复杂度虽然相同,但是造成的原因不同。

0 0
原创粉丝点击