資料結構&演算法實踐——Python
第一部分列表(目錄主要來自於維基百科)
模組一:經典排序實現
交換排序法
氣泡排序 |雞尾酒排序 |奇偶排序 |梳排序 |地精排序(gnome_sort) |Bogo排序|快速排序
選擇排序法
選擇排序 | 堆排序
插入排序法
插入排序 | 希爾排序 | 二叉查詢樹排序 | Library sort | Patience sorting
歸併排序法
歸併排序 | Strand sort
非比較排序法
基數排序 | 桶排序 | 計數排序 | 鴿巢排序 | Burstsort | Bead sort
其他
拓撲排序 | 排序網路 | Bitonic sorter | Batcher odd-even mergesort | Pancake sorting
低效排序法
Bogosort | Stooge sort
模組二:經典查詢
模組三:資料結構(後續補充完整,樹和圖是大頭,包含很多分類和經典演算法)
線性表 佇列 棧 堆 樹 圖
————————————–目錄 END————————————————
寫在前面
畢業迄今也接近一年了,發現很多學校的東西似乎生疏了.
最近重新拿起資料結構,演算法導論,離散數學,決定用程式碼敲些東西,權當複習
大部分的地方我只會給出例子和具體的程式碼實現,順帶給出一些百科的連結,概念和理論性的東西網上都有,不贅述了 之所以選擇用python來寫,主要是python的可讀性非常好,即使不寫註釋,也能很輕鬆讀懂.
我把這個過程大概切成三個部分:
1.經典資料結構和演算法的實現
實現基本的經典演算法,包括經典排序,經典查詢,索引等,基本實現及改進
實現基本的資料結構,包括線性表,佇列,棧,堆,樹,圖等,包含擴充套件
使用實現類似Java的資料結構,至始至終都認為java的api最為優美,使用Python實現之,包括Map,List,Set等,提供相同的API,同時希望會循序漸進,先用簡單直觀的方法實現,給出優化,涉及的知識主要是python物件導向,繼承,重寫內建方法,封裝,(要對Python和java資料結構實現的底層原始碼有了解,需要看原始碼)
2.筆試題面試題資料結構和演算法實現
筆試&面試題的python處理
使用Python搞定筆試題&面試題中出現的演算法和資料結構題目
包含大規模資料處理的詳細例子
3.challenge
挑戰一些大個的東西,深入實現一些較為複雜的演算法
不羅嗦,先列下目錄,已經寫完一部分了,逐步發出來,更新目錄(挪到前頭去了) 先列這些,逐漸補充.
每天上完班回來,啃這堆磚頭,然後敲出來,累卻充實.
敲程式碼,除錯程式碼其實是一件十分快樂的事情
My daytime job is SDET,平時敲自己喜歡的程式碼的時間並不會太多,業餘時間有限
但做事貴善始善終,會堅持搞完的哈! The End!
wklken@yeah.net
2012-05-10
排序>>交換排序>>雞尾酒排序
List:
1 2 3 |
0.概念+虛擬碼+示例分析 1.雞尾酒排序實現 2.Question |
- start
基本概念:
維基百科http://zh.wikipedia.org/wiki/%E9%B8%A1%E5%B0%BE%E9%85%92%E6%8E%92%E5%BA%8F
虛擬碼:
1 2 3 4 5 6 7 8 9 10 11 12 |
function cocktail_sort(A: list[1..n]){ for i from 0 to n/2{ for f from i to (n-i-2){ if(A[a] > A[a+1]) swap(A[a],A[a+1]) } for b from (n-i-2) to (i+1){ if(A[b] A[b-1]) swap(A[b],A[b-1] } } } |
雞尾酒排序是氣泡排序的變種——雙向氣泡排序
從虛擬碼可以看到,每一輪迴圈,從前到後一次正向冒泡,之後從後往前再進行一次逆向冒泡(每一輪存在兩個數被排序)
可以看到的表現是兩邊先排序好,逐漸向中間有序
示例:
1 2 3 4 5 |
->[50, 10, 30, 20, 60, 40, 1] -> [10, 30, 20, 50, 40, 1, 60] 第一輪正向 -> [1, 10, 30, 20, 50, 40, 60] 第一輪逆向 -> [1, 10, 20, 30, 40, 50, 60] 第二輪正向 -> [1, 10, 20, 30, 40, 50, 60] 第二輪逆向,無交換,結束 |
詳細比較過程:
1 |
[50, 10, 30, 20, 60, 40, 1] |
第一輪 正向
1 2 3 4 5 6 7 8 9 10 11 |
l->r cmp 50 10 change [10, 50, 30, 20, 60, 40, 1] l->r cmp 50 30 change [10, 30, 50, 20, 60, 40, 1] l->r cmp 50 20 change [10, 30, 20, 50, 60, 40, 1] l->r cmp 50 60 l->r cmp 60 40 change [10, 30, 20, 50, 40, 60, 1] l->r cmp 60 1 change [10, 30, 20, 50, 40, 1, 60] |
第一輪 逆向
1 2 3 4 5 6 7 8 9 10 |
r->l cmp 1 40 change [10, 30, 20, 50, 1, 40, 60] r->l cmp 1 50 change [10, 30, 20, 1, 50, 40, 60] r->l cmp 1 20 change [10, 30, 1, 20, 50, 40, 60] r->l cmp 1 30 change [10, 1, 30, 20, 50, 40, 60] r->l cmp 1 10 change [1, 10, 30, 20, 50, 40, 60] |
[1, 10, 30, 20, 50, 40, 60]
第二輪 正向
1 2 3 4 5 6 |
l->r cmp 10 30 l->r cmp 30 20 change [1, 10, 20, 30, 50, 40, 60] l->r cmp 30 50 l->r cmp 50 40 change [1, 10, 20, 30, 40, 50, 60] |
第二輪 逆向
1 2 3 4 5 |
r->l cmp 40 30 r->l cmp 30 20 r->l cmp 20 10 [1, 10, 20, 30, 40, 50, 60] (上一輪逆向無交換,結束排序) [1, 10, 20, 30, 40, 50, 60] |
本陣列共比較18次,而使用帶標誌氣泡排序需要21次
- start
實現程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
def cocktail_sort(l): size = len(l) sign = 1 #用於判斷上輪排序是否存在資料交換 for i in range(size / 2): if sign: sign = 0 #正向,冒泡 從 i 到 對稱的位置-1 for j in range(i, size - 1 - i): if l[j] > l[j + 1]: l[j], l[j + 1] = l[j + 1], l[j] #逆向,冒泡 從正向排完最大數的前一個開始,到 i for k in range(size - 2 - i, i, -1): if l[k] l[k - 1]: l[k], l[k - 1] = l[k - 1], l[k] sign = 1 #若是逆向存在交換,代表還沒排序完成,否則,排序完成 else: break print l |
改換成while
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def cocktail_sort2(l): size = len(l) sign = 1 #用於判斷上輪排序是否存在資料交換 i = 0 while sign: sign = 0 for j in range(i, size - 1 - i): if l[j] > l[j + 1]: l[j], l[j + 1] = l[j + 1], l[j] for k in range(size - 2 - i, i, -1): if l[k] l[k - 1]: l[k], l[k - 1] = l[k - 1], l[k] sign = 1 #若是逆向存在交換,代表還沒排序完成,否則,排序完成 i += 1 |
也可以維護一個bottom和top,每次bottom+1,top-1
- start
A.雞尾酒排序概念,過程描述?
B.最差,平均,最優 時間複雜度?
最差=平均=O(n^2) 最優=O(n)
C.空間複雜度?
D.是否是穩定排序?
E.存在什麼方法可以更優化
F.適用場景,什麼情況下最優,什麼情況下最差?
—————————————– END ————————————————-
p.s.維基百科的動態排序圖很贊&坑爹好幾種排序無中文描述,只能啃英文版的百科了,到時候一塊貼了
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式