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

15 篇文章 0 订阅
12 篇文章 0 订阅

一、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/pospro
def shellSort(alist):
	step=4		#初始步长采用4
	while 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//2


def shellSortCore(alist, startpos, step):
	#这个函数其实就是实现了一个step版的插入算法,
	#不熟悉插入算法的话,可以看前一篇博客:http://blog.csdn.net/pospro/article/details/48091893
	n=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-=step
		alist[newpos]=val #退出循环后,newpos指示的就是val该放置的位置
		idx+=step
	print alist  #仅为动态显示过程之用

三、测试用例和输出

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

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

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





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值