用Python实现基本排序算法04——Shell排序

来源:互联网 发布:centos 6.5 计划任务 编辑:程序博客网 时间:2024/06/06 16:41

一、Shell排序的思路

        Shell排序实质上是一种优化的插入排序。D.L.Shell在研究后发现,插入排序存在以下规律:

        1>在元素基本有序时效率较高,

        2>在序列规模较小时效率较高

        为了充分利用这个两个规律,Shell排序的思路是:

a>设定步长,每隔一段距离取一个数,将原来需要排序的序列变成几个较小的部分(姑且称之为子串吧),这样就可以满足2>的条件。

b>将每个子串各自排序

c>减小步长,形成新的子串。此时的子串虽然包含更多地元素,但由于经过b>步骤的排序,此时各部分已基本有序,故满足了1>的设定

d>逐次减小步长,最后进行一次步长为1的排序(也即正常的插入排序),但此时整个串已经基本有序,交换次数不会太多,效率会很高。


二、程序实现

在具体实现时步长(Step)的取法并不固定,在数据量较大时不同的Step取法将带来不同的优化效果(根据网上的说法,PosPro未做研究)。

这里仅仅为了说明算法实现的思路,Step取4,2,1,按照从小到大排列。

#20150901 by PosPro# http://blog.csdn.net/posprodef shellSort(alist):step=4#初始步长采用4while step>=1:  #step=1时就是最后一次排序for i in range(step): # i=0,1,...step-1, 恰好是每一个子串起始值所在位置shellSortCore(alist, i, step)print 'Num in every %d positon has been sorted'%step  #动态显示之用step=step//2def shellSortCore(alist, startpos, step):#这个函数其实就是实现了一个step版的插入算法,#不熟悉插入算法的话,可以看前一篇博客:http://blog.csdn.net/pospro/article/details/48091893n=len(alist)  #记录alist的长度idx=startpos+step  #idx恰好是未排序子串中第一个元素的位置while idx<n:val=alist[idx]  #待插入的值,也即未排序子串中第一个元素的值newpos=idx      #待插入值得位置,初始值为排在有序子串的最后while alist[newpos-step]>val and newpos>startpos: #若待插入位置不合适,则通过平移,继续寻找alist[newpos]=alist[newpos-step] #注意这里所有位置的增减都是针对步长值操作的newpos-=stepalist[newpos]=val #退出循环后,newpos指示的就是val该放置的位置idx+=stepprint alist  #仅为动态显示过程之用

三、测试用例和输出

可使用以下代码对算法进行测试:

list1=[9,8,11,3,4,10,6,0,2,1,7,5]print list1shellSort(list1)print list1

输出结果如下,仔细分析一下,就可以体会出Shell算法的处理过程。





0 0
原创粉丝点击