希尔排序
#引用书籍以及地址
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)