思路:
希爾排序其實就是插入排序的一種,把原有序列分為gap個子序列,每乙個子串行都執行插入排序的操作(是在原有序列上進行) 然後把gap變小,就有會生成gap個子序列,對每乙個新的子串行繼續執行插入排序操作,gap=1時 其實就是對原有長度序列執行的插入排序;
def執行結果:shell_sort(l):
"""希爾排序
"""n=len(l)
gap = int(n/2)
while gap>0: #
gap:4-->2--->1變化(可以自己設定gap的長度,每次減小)
for i in range(gap): #
gap=4為例,原有序列會被拆成4個子序列進行處理,每乙個子串行進行插入排序 (但是不改變原有序列,只是在原來的基礎上進行)
j=i+gap #
比如對於第乙個子串行,首先需要考慮i=0+4位置的元素,把它放在前面有序序列的哪個位置
while j
for k in range(j,0,-gap): #
就是把需要插入的元素跟前面有序序列的元素進行比較(從後往前) 看把待插入的元素放在哪個位置
if l[k]gap]:
l[k],l[k-gap]=l[k-gap],l[k]
else: #
如果待插入的元素比前面有序序列最後乙個位置元素還大 就不需要在進行比較了,待插入元素直接就是放在前面有序序列的最後位置
break
j=j+gap #
進行下乙個待插入元素的比較判斷插入操作
gap=int(gap/2) #
不斷減小gap gap=1其實對應的就是對整個序列進行插入排序的操作
return
lprint(shell_sort([3,6,1,7,2,9,5,8]))
希爾排序的時間複雜度仍然是o(n^2) -----因為希爾排序的本質仍然是插入排序;
希爾排序是不穩定的,比如gap=4時 產生的四個子串行都需要進行插入排序的操作,如果原序列有兩個12 有可能在後面的那個12在第乙個子串行中執行完插入排序後排在了最前面,但是 前面的12 在第二個子串行執行插入排序有可能排在了最後,這種情況是跟子串行中其他元素大小相關的,相同的元素 位於後面的有可能在子串行中排在了前面,所以希爾排序是不穩定的~
自己寫的那個**效率太低(四層迴圈),其實每取乙個gap都會對應產生gap個子序列,沒必要分開對gap個子序列分別執行插入排序,可以同時進行,也就是可以挨個對後面的待插入的元素進行比較,但是比較的物件都是基於自身gap個間隔的物件元素~(說起來有點繞,一句話總結就是還跟之前插入排序的思路一樣,對後續所有待插入的元素同時進行遍歷,原本是1位置開始一直到最後,現在是gap位置開始,一直到最後,原本是對每乙個待插入的元素跟前面所有元素進行比較執行插入排序,現在是對每乙個帶插入排序的元素跟前面相差gap的子串行進行比較執行插入排序!!!)
def執行結果:shell_sort(l):
"""希爾排序
"""n=len(l)
gap=n//2
while gap>0: #
把原有序列根據gap間隔劃分子串行,對每乙個子串行進行插入排序,gap=1就是對原有長度的序列執行一次插入排序
for i in range(gap,n): #
首先從gap位置的元素開始,跟前面序列位置元素進行比較(相差gap) 執行插入排序
for j in range(i,0,-gap):
if l[j]gap]:
l[j],l[j-gap]=l[j-gap],l[j]
else
:
break
gap=gap//2
return
lprint(shell_sort([3,6,1,7,2,9,5,8]))
python資料結構與演算法
coding utf 8 import sys 使用以下語句將引數的str格式轉換為int格式 l list map int sys.argv 1 split target int sys.argv 2 def binarysearch print l print target left 0 rig...
資料結構與演算法 python
元類 基礎 冒泡 它重複地走訪要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢 浮 到數列的頂端,故名氣泡排序。def bubble sort alist ...
python演算法與資料結構
若n1 n2 n3 1000,且n1平方 n2平方 n3平方 n1,n2,n3為自然數 求出所有n1 n2 n3可能的組合?n1 0 n2 0 n3 0 判斷n1 n2 n3是否等於1000,之後變n3 1,n3 2,n3 3,然後再變n2 那如果變為 n1 n2 n3 2000 了呢?思路1 實現...