[Python-*-算法]希尔排序

希尔排序

#引用书籍以及地址 

Solving with Algorithms and Data Structures

原文中有在线调试的功能,很好用

简要说明:


    希尔排序,有时也叫做“最小增量排序”,通过把原始的序列分解成几个子序列来提高效率,其中每个小序列使用的都是插入排序。怎么样划分这些子序列是希尔排序的关键。希尔排序不是直接把整个序列直接分割成连续的子序列,而是用了一个增量i,有时也叫做gap(间隔),通过选择i划分的list组成子序列。


请参见图6。整个list有9个元素,如果我们使用3为增量,就会有3个子list,每个子list可以使用插入排序。所有子列表完成排序后,我们就可以得到图7 。尽管结果并没有完全排序,但发生了一些很有意思的事情。通过对子序列的排序,我们把这些元素放到离最终排序结果很近的地方。



图6


图7


图8显示了使用一个增量的最插入排序,换句话说就是标准的插入排序。注意通过前面的子list 的排序,我们现在已经减少了整个排序
的总操作次数。最多只要4次移位就可以完成整个过程。


图8 


图9 


前面我们说过,怎样去选择排序分割的增量是希尔排序的独特的特性。示例代码中我们就使用了不同的增量。这次我们开始用的是n/2个的子序列。然后,n/4个子序列。最后,整个list最后经过出一次基本的插入排序。图9就是我们使用这种增量的例子。

下面shellSort函数的调用显示了每次增量后的部分排序,在最后的插入排序之前从1个增量开始排序。

代码

#utf8.py
#python2.7 sellSort.py
def shellSort(alist):
    sublistcount = len(alist)//2  #计算取子列表的增量 第一次是4  ex:alist[0] alist[4] alist[8]为一个子组
    while sublistcount > 0:   #第二次sublistcount=2 ex:alist[0] alist[2] alist[4] alist[6] alist[8]为一个子组


      for startposition in range(sublistcount):
        gapInsertionSort(alist,startposition,sublistcount)  


      print("After increments 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 = [54,26,93,17,77,31,44,55,20] #将要排序列表 
shellSort(alist)  #调用排序
print(alist)



posted @ 2013-04-22 20:40  坚固66  阅读(166)  评论(0编辑  收藏  举报