10_python_Insertion Sort and Shell Sort

插入排序

  • 插入排序的时间复杂度为O(n^2)
  • 插入排序维持一个已排好序的子列表,其位置始终在列表的前部,然后逐步扩大这个子列表直到全表。(类似于打牌时整理扑克牌)
    • 第1趟,子列表仅包含第1个数据项,将第2个数据项作为‘新项’插入到子列表的合适位置中,这样已排序的子列表就包含了2个数据项
    • 第2趟,再继续将第3个数据项跟前2个数据项比对,并移动比自身大的数据项,空出位置来,以便加入到子列表中
      ……
    • 经过n-1趟比对和插入,子列表扩展到全表,排序完成。
  • 插入排序的比对主要用来寻找‘新项’的插入位置,移动所有比‘新项’大的数据项
    • 最差情况是每趟都与子列表中所有项进行比对,总比对次数与冒泡排序相同,数量级仍然是:O(n^2)
    • 最好情况,列表已经排好序的时候,每趟仅需1次比对,总次数是:O(n)
def insertionSort(alist):
    for index in range(1, len(alist)):
        
        currentvalue = alist[index]  #新项
        position = index
        
        while position > 0 and alist[position - 1] > currentvalue:
            alist[position] = alist[position - 1]  #比新项大的数据项向后移动
            position = position - 1
        
        alist[position] = currentvalue  #插入新项

alist = [1, 9, 3, 10, 8, 2, 0, 10]
insertionSort(alist)
print(alist)
[0, 1, 2, 3, 8, 9, 10, 10]

由于移动操作仅包含一次赋值,是交换操作的1/3,所以插入排序性能会比较好一些。

希尔排序

我们注意大插入排序的比对次数,在最好情况下是O(n),这种情况发生在列表是有序的情况下,实际上,列表越接近有序,插入排序的比对次数就越少。

  • 希尔排序以插入排序为基础,对无序表进行间隔划分子列表,每个子列表都执行插入排序。
    • 子列表的间隔一般从n/2开始,每趟倍增:n/4,n/8……直到1。
    • 随着子列表的数量越来越少,无序表的整体越来越接近有序,从而减少整体排序的比对次数。
    • 最后一趟是标准的插入排序,但由于前面几趟已经将列表处理到接近有序,这一趟仅需少数几次移动即可完成。
def shellSort(alist):
    sublistcount = len(alist) // 2  #间隔初始设定
    while sublistcount > 0:
        for startposition in range(sublistcount): #子列表排序
            gapInsertionSort(alist, startposition, sublistcount)
        print("After incerments of size",sublistcount,"The list is",alist)
        
        sublistcount = sublistcount // 2  #间隔缩小

def gapInsertionSort(alist, start, gap):
    for i in range(start + gap, len(alist),gap):
        currentvalue = alist[i]
        position = i
        
        while position >= gap and alist[position - gap] > currentvalue:
            alist[position] = alist[position - gap]
            position = position - gap
        alist[position] = currentvalue

alist = [1, 9, 3, 10, 8, 2, 0, 10]
shellSort(alist)
print(alist)
[0, 1, 2, 3, 8, 9, 10, 10]
  • 由于每趟排序都使得列表更加接近有序,这过程会减少很多原先需要的‘无效’比对。
    • 对希尔排序的详尽分析比较复杂,大致说是介于O(n)和O(n^2)之间
    • 如果将间隔保持在2^k-1 (1,3,5,7,15,31……),希尔排序的时间复杂度约为O(n^1.5)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值