shellsort排序有趣的試驗
shellsort排序有趣的試驗
今天和同事討論關於一個shell排序的問題。
原因是在<演算法>這本書上看到的方法,其中程式碼就不貼出來了,因為效率不是十分高。那麼同事給我演示的是23秒
多,資料量是100萬。我當時用python寫了半天也沒逾越這個數!我們機器是一樣的配置一樣的型號,幾乎沒有不同,除了密碼!處理器是i5 2450 4核心,使用的是同樣的資料樣本。我用的是python2.5,他使用的是python2.7。因為程式是在同一個機器上跑的,跑完到另一個機器跑。
wiki版本(不少網站都會貼著個程式碼)
def shellSort(array):
"Shell sort using Shell's (original) gap sequence: n/2, n/4, ..., 1."
gap = len(array) // 2
# loop over the gaps
while gap > 0:
# do the insertion sort
for i in range(gap, len(array)):
val = array[i]
j = i
while j >= gap and array[j - gap] > val:
array[j] = array[j - gap]
j -= gap
array[j] = val
gap //= 2
然後我發現我程式碼的中間變數和冗餘程式碼十分多,我嘗試砍掉中間變數。我們就用中間修改差不多的原始版本吧,我們這裡做為第一版本!
def sort(a):
n = len(a)
h = n // 2
while h > 0:
#print h
for i in xrange(h , n):
val = a[i] #注意這個地方
for j in xrange(i,h-2,-h):
if a[j-h] > val : temp = a[j-h] ; a[j-h] = a[j] ; a[j] = temp
else: break
h //= 2
第1次修改
這個版本我修改掉了交換值,這個小小的增加一個開銷pack和unpack的時候,總體會增加不到0.01秒。但程式碼的可讀性很高!
def sort(a):
n = len(a)
h = n // 2
while h > 0:
#print h
for i in xrange(h , n):
val = a[i]
for j in xrange(i,h-2,-h):
if a[j-h] > val : a[j],a[j-h] = a[j-h],a[j]
else: break
h //= 2
第2次修改:
這裡很重要,我修改掉了else。這裡用了一個測試中看到的
情況1
。就是如果子條件內進行for迴圈時,如果發現需要交換的變數,那麼迴圈可以結束!
這個直接減少了大概10秒左右的開銷,也就是接近,有的時候會快過wiki版本的平均值。
def sort(a):
n = len(a)
h = n // 2
while h > 0:
#print h
for i in xrange(h , n):
val = a[i]
for j in xrange(i,h-2,-h):
if a[j-h] > val : a[j],a[j-h] = a[j-h],a[j] ; break
h //= 2
最終版本:
這裡我去掉了臨時變數,這裡很關鍵,秒殺wiki版本的另一個重要
情況2
:情況1
發生的前置條件中的被對比值必然是要交換的值。
根據這個直接改掉程式,秒殺接近4個秒單位!
def sort(a):
n = len(a)
h = n // 2
while h > 0:
for i in xrange(h , n):
for j in xrange(i,h-2,-h):
if a[j-h] > a[j] : a[j],a[j-h] = a[j-h],a[j] ; break
h //= 2
這裡為什麼說是情況,而不是說定理?因為我證明不了。。哈哈。這個過程太複雜。 至此,算是7行解決了這個問題,從時間開銷和程式碼行數都完爆wiki版本的程式。
總結:感謝圖靈能夠出版<演算法>這本書的翻譯版本,更感謝@一盆花 謝大給我們帶來這麼好的書。只有思考才會發現,只有發現才能改變,改變錯了,再思考,呵呵。
相關文章
- 有趣的桶排序排序
- 日本的“Google實驗室”:有趣法人KAYACGo
- C#資料結構與演算法系列(二十一):希爾排序演算法(ShellSort)C#資料結構演算法排序
- 陣列排序的測試陣列排序
- 一些有趣的B+樹優化實驗優化
- 聊一聊那些腦洞大開、有趣又奇葩的排序演算法排序演算法
- 筆試之排序-直接插入排序、氣泡排序、快速排序筆試排序
- 【rlwrap】讓rlwrap工具更加的生動有趣——快捷鍵的嘗試
- 從有趣的數字遊戲中,獲得的JavaScript學習經驗遊戲JavaScript
- 有趣的cssCSS
- 氣泡排序(機試題)排序
- 快速排序(java機試題)排序Java
- 帶你深入 Dart 解析一個有趣的引用和編譯實驗Dart編譯
- 有趣的翻譯
- 在杉果π現場,我試玩了這四款有趣的獨立遊戲遊戲
- 插入排序(java機試題)排序Java
- 選擇排序(java機試題)排序Java
- 歸併排序(java機試題)排序Java
- 資料排序_麥克機試排序
- 測試經驗總結:測試員的角色
- 反向代理的有趣用法
- 有趣的DBA面試題面試題
- 一個有趣的sqlSQL
- 有趣的html頁面HTML
- 有趣的演算法演算法
- 動態試驗
- oracle profile 試驗Oracle
- 來自蘋果、谷歌、微軟等知名公司六道有趣智力面試題,試試吧!蘋果谷歌微軟面試題
- 十年測試經驗悟出的測試心得
- ORACLE的使用試驗-- RMAN之一Oracle
- 厭倦了程式設計書?來試試這3種提高程式設計技能的有趣方法吧程式設計
- C++17 並行排序初體驗C++並行排序
- 經典氣泡排序的分析、優化及測試排序優化
- kdb+/q的列表排序和查詢效能測試排序
- 有趣的程式碼註釋
- 有趣的CSS彈跳動畫CSS動畫
- 有趣的正則填字遊戲遊戲
- 有趣的數學公式(一)公式