直接插入排序和希尔排序

来源:互联网 发布:个人可以开淘宝网店吗 编辑:程序博客网 时间:2024/04/30 07:58

一、直接插入排序(插入排序)
1.1 基本思想和原理
  将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
  要点:设立哨兵,它有两个作用:
  ① 进入查找(插入位置)循环之前,它保存了R[i]的副本,使不致于因记录后移而丢失R[i]的内容;
  ② 它的主要作用是:在查找循环中”监视”下标变量j是否越界。一旦越界(即j=0),因为R[0]可以和自己比较,循环判定条件不成立使得查找循环结束,从而避免了在该循环内的每一次均要检测j是否越界(即省略了循环判定条件”j>=1”)。
  直接插入排序的实例如下图所示:

这里写图片描述

1.2 python实现的代码

def straightInsert(nums):# 直接插入排序: 小->大    for i in range(1, len(nums)):        index = nums[i]        j = i - 1        while j >= 0 and nums[j] > index:            nums[j + 1] = nums[j]  # 前面的大值先赋给后面的值,往后移动            j -= 1        nums[j + 1] = index  # 将数据插入到正确的位置    return numsif __name__=='__main__':    s = [3, 4, 1, 6, 2, 9, 7, 0, 8, 5]    print(straightInsert(s))

1.3 总结
直接插入排序的时间复杂度是O(n2)。它是一种稳定排序的算法。

二、希尔排序(插入排序)
2.1 基本思想
  希尔排序的实质就是分组插入排序,相对直接插入排序有较大的改进,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。
  该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前三种方法有较大提高。
  希尔排序的思想如下图实例所示:

这里写图片描述

2.2 python实现的代码
  先将要排序的一组记录按某个增量d(n/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d。对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。继续不断缩小增量直至为1,最后使用直接插入排序完成排序。

def shellSort(nums):    # 设定步长    step = len(nums)/2    while step > 0:        for i in range(step, len(nums)):            # 类似插入排序, 当前值与指定步长之前的值比较, 符合条件则交换位置            while i >= step and nums[i-step] > nums[i]:                nums[i], nums[i-step] = nums[i-step], nums[i]                i -= step        step = step/2    return numsif __name__ == '__main__':    nums = [9,3,5,8,2,7,1]    print shellSort(nums)

2.3 总结
  希尔排序时效分析很难,关键码的比较次数与记录移动次数依赖于增量因子序列d的选取,特定情况下可以准确估算出关键码的比较次数和记录的移动次数。目前还没有人给出选取最好的增量因子序列的方法。增量因子序列可以有各种取法,有取奇数的,也有取质数的,但需要注意:增量因子中除1 外没有公因子,且最后一个增量因子必须为1。希尔排序方法是一个不稳定的排序方法。
  不过需要说明的是大量研究表明,当增量序列为d[k]=2t-k+1-1时,希尔排序的时间复杂度为O(n1.5),其中t为排序趟数,这个排序的时间复杂度是要好于直接插入排序的O(n2)。

原创粉丝点击