一、選擇排序:每步從待排序的元素中選出關鍵字最小的元素,順序放在已經排序的元素序列的最後,直到全部排完爲止。
常見的選擇排序有簡單選擇排序和堆排序
1.簡單選擇排序
1)過程:假設元素存放在R[0..n-1]之中,其中R[0..i-1]是有序的,R[i..n-1]是無序的,且有序的所有元素均小於無序的元素。需將R[i]添加到[0..i-1]之中,使R[0..i]有序。查找的過程是每一趟從R[i..n-1]中選擇一個最小關鍵字的元素R[k],將其與R[i]進行交換,這樣R[0..i]就變成新的有序序列了。
2)python實現:
def sort6(a):
#假設左邊已有序,右邊爲待排序列
for i in range(0,len(a)-1):
# i = [0,1,2...len(a)-2]
# j = [i+1,i+2...len(a)-1]
tmp = i
for j in range(i+1,len(a)):
#從右邊待排序列中找到一個最小的元素
if a[j] < a[tmp]:
tmp = j
#待排序列中存在比a[i]小的元素
if tmp != i:
a[tmp],a[i] = a[i],a[tmp]
return a
3)複雜度
空間複雜度:O(1)
時間複雜度:
平均 O( )
最好O( )
最壞 O( )
2.堆排序
1)過程:利用堆進行排序的一種算法。堆就是一種完全二叉樹,有如下分類:
大根堆:每個節點的值都大於或者等於左右孩紙節點(左右孩紙節點大小沒有要求)
小根堆:每個節點的值都小於或者等於左右孩紙節點(左右孩紙節點大小沒有要求)
2)python實現:
待補充
3)
3)複雜度
空間複雜度:O(1)
時間複雜度:
平均 O( nlog2n)
最好 O( nlog2n)
最壞 O( nlog2n)
二、各種排序算法比較
各種常用排序算法 |
||||||||
類別 |
排序方法 |
時間複雜度 |
空間複雜度 |
穩定性 |
複雜性 |
特點 |
||
最好 |
平均 |
最壞 |
輔助存儲 |
|
簡單 |
|
||
插入 排序 |
直接插入 |
O(N) |
O(N2) |
O(N2) |
O(1) |
穩定 |
簡單 |
|
希爾排序 |
O(N) |
O(N1.3) |
O(N2) |
O(1) |
不穩定 |
複雜 |
|
|
選擇 排序 |
直接選擇 |
O(N) |
O(N2) |
O(N2) |
O(1) |
不穩定 |
|
|
堆排序 |
O(N*log2N) |
O(N*log2N) |
O(N*log2N) |
O(1) |
不穩定 |
複雜 |
|
|
交換 排序 |
冒泡排序 |
O(N) |
O(N2) |
O(N2) |
O(1) |
穩定 |
簡單 |
1、冒泡排序是一種用時間換空間的排序方法,n小時好 |
快速排序 |
O(N*log2N) |
O(N*log2N) |
O(N2) |
O(log2n)~O(n) |
不穩定 |
複雜 |
1、n大時好,快速排序比較佔用內存,內存隨n的增大而增大,但卻是效率高不穩定的排序算法。 |
|
歸併排序 |
O(N*log2N) |
O(N*log2N) |
O(N*log2N) |
O(n) |
穩定 |
複雜 |
1、n大時好,歸併比較佔用內存,內存隨n的增大而增大,但卻是效率高且穩定的排序算法。 |
|
基數排序 |
O(d(r+n)) |
O(d(r+n)) |
O(d(r+n)) |
O(rd+n) |
穩定 |
複雜 |
|
|
注:r代表關鍵字基數,d代表長度,n代表關鍵字個數 |
ps:排序算法的穩定性:
排序結束後,原來數據中的相同的元素能保持原有的順序不變,那這種排序算法就是穩定的。(比如常見的冒泡排序、基數排序、插入排序、歸併排序、桶排序、二叉樹排序等都是穩定的排序算法tip:插入 雞(基)and 龜(歸)—>桶冒泡,可以這樣聯想記憶!)
反之,如果不能保證原有順序,這種算法就是不穩定的。(比如常見的選擇排序,希爾排序,堆排序,快速排序等都是不穩定的排序算法)
要證明一種排序算法不穩定,舉出一組例子就OK了;但要證明算法穩定,就要對算法設計進行徹底分析了。
再補充一個概念:
精儉排序/節儉排序(一對數字不進行兩次和兩次以上的比較):
插入排序,歸併排序