【面试专题07】Python全栈日记-希尔排序

在写这篇日记之前我看了好多别人写的,大同小异,但是大家都存在的区别就在于间隔增量如何取,而且虽然程序确实能够执行,但是也都避重就轻没有解释如果列表元素为奇数个时思路是如何的。

 

本次笔记在(https://www.cnblogs.com/jsgnadsj/p/3458054.html)基础上进行一些扩展。

 

 

直接插入排序在在本身数量比较少的时候情况下效率很高,如果待排数的数量很多,其效率不是很理想。   

回想一下直接插入排序过程,排序过程中,我们可以设置一条线,左边是排好序的,右边则是一个一个等待排序,

如果最小的那个值在最右边,那么排这个最小值的时候,需要将所有元素向右边移动一位。

 

是否能够减少这样的移位呢?

我们不希望它是一步一步的移动,而是大步大步的移动。希尔排序就被发明出来了,它也是当时打破效率O(n2)的算法之一。希尔排序算法通过设置一个间隔,对同样间隔的数的集合进行插入排序,此数集合中的元素移位的长度是以间隔的长度为准,这样就实现了大步位移。但是最后需要对元素集合进行一次直接插入排序,所以最后的间隔一定是1。

 

初始状态:

取间隔增量gap=数组长度整除2,得出增量为5,然后从下标为5的元素开始,取当前元素和当前元素下标减去增量的元素作为一组,也就是下标5和下标0,下标6和下标1,以此类推,如果是列表为奇数个,则会多余出一个元素。把多余的元素放在第一组中排序。

如果是奇数个是这样:并不要求每组中数一样,但是间隔必须相等。

 

对这五组数进行直接插入排序,结果变为:

3,5,1,6,0,8,9,4,7,2

 

然后缩小增量,对原有增量再次折半gap=gap//2,得出新的gap为2,,再次分组,再使用直接插入排序进行排序。

 

 

 

Python代码实现

结果:

[4, 13, 27, 34, 38, 49, 49, 55, 65, 76, 97]

 

推荐大家使用debug,自己取推演程序运行的过程,会相当方便理解,也用于检查自己程序错误·,pycharm中右键debug

 

 

优劣

不需要大量的辅助空间,和归并排序一样容易实现。希尔排序是基于插入排序的一种算法, 在此算法基础之上增加了一个新的特性,提高了效率。希尔排序的时间复杂度与增量序列的选取有关。此外,希尔算法在最坏的情况下和平均情况下执行效率相差不是很多,与此同时快速排序在最坏的情况下执行的效率会非常差。专家们提倡,几乎任何排序工作在开始时都可以用希尔排序,若在实际使用中证明它不够快,再改成快速排序这样更高级的排序算法. 本质上讲,希尔排序算法是直接插入排序算法的一种改进,减少了其复制的次数,速度要快很多。 原因是,当n值很大时数据项每一趟排序需要移动的个数很少,但数据项的距离很长。当n值减小时每一趟需要移动的数据增多,此时已经接近于它们排序后的最终位置。 正是这两种情况的结合才使希尔排序效率比插入排序高很多。Shell算法的性能与所选取的分组长度序列有很大关系。只对特定的待排序记录序列,可以准确地估算关键词的比较次数和对象移动次数。想要弄清关键词比较次数和记录移动次数与增量选择之间的关系,并给出完整的数学分析,今仍然是数学难题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值