1. 程式人生 > >主要排序演算法總結

主要排序演算法總結

一、穩定排序與不穩定排序

  相等的元素排序之後相對位置不變就是穩定排序,反之就是不穩定排序。

二、主要排序演算法

  1、氣泡排序

    思想:遍歷列表裡的每個元素,每趟遍歷的元素都與後面的元素進行比較,

       如果大於下一個元素就交換位置,如果小於下一個元素就不交換,最終都找到最大的放在列表最後,遍歷的趟數就是列表長度減1。    

      # 最小比較次數   C = n - 1
      # 最小交換移動次數 M = 0
      # 時間複雜度為 O(n)

      # 最大比較次數 C = n*(n-1)/2
      # 最大交換移動次數 M = 3n*(n-1)/2
      # 時間複雜度為 O(n**2)

      # 總的平均時間複雜度為O(n**2)
  程式碼:
    
def bubble_sort(l):
for i in range(len(l)-1):
for j in range(0, len(l)-i-1):
if l[j] > l[j+1]:
l[j], l[j+1] = l[j+1], l[j]
print(l)


import random
l = random.sample(range(1, 100), 20)
print(l)
bubble_sort(l)                                                                                             

  2、直接插入排序

    思想:  # 把列表看成是有序列表和無序列表的組合,剛開始有序列表是第一個元素,然後從第二個元素開始遍歷列表,即遍歷無序列表,讓無序列表中的每一個元素都跟有序列表的元素進行比較

        # 所以第一個for迴圈就是遍歷無序列表,第二個for迴圈就是倒序遍歷有序列表,然無序列表的元素與有序列表的元素進行比較,如果小於有序列表的元素就交換位置,反之就退出有序列表

         的比較迴圈,進行下一個無序列表元素與有序列表的的比較迴圈

    程式碼:    

 1 import random
 2
3 l = random.sample(range(1, 101), 20) 4 print(l) 5 6 for i in range(0, len(l)-1): 7 for j in range(i+1, 0, -1): 8 if l[j] < l[j-1]: 9 l[j], l[j-1] = l[j-1], l[j] 10 else: 11 break 12 print(l)
View Code

  3、希爾排序

    思想:按照一定的步長把列表分組,然後每組列表再按照插入排序演算法排序,步長就是列表的長度整除2,直到步長小於1結束分組。

    程式碼:  

 1 import random
 2 
 3 l = random.sample(range(1, 101), 20)
 4 print(l)
 5 d = len(l)//2  # 步長
 6 while d >= 1:
 7     for i in range(d):  # 分了d組新列表
 8         # 每個新列表使用直接插入法排序
 9         for j in range(i, ((len(l)//d)-1)*d, d):  # 遍歷新列表(無序列表),最後一個元素不用遍歷
10             for k in range(j+d, i, -d):  # 遍歷有序列表,依次比較
11                 if l[k] < l[k-d]:  # 從小到大排序
12                     l[k], l[k-d] = l[k-d], l[k]
13                 else:
14                     break
15     d = d // 2
16 print(l)
View Code

 

  4、選擇排序

    思想:# 把整個列表看成是有序列表和無序列表的組合,剛開始有序列表為空,每次從無序列表中選出最小的值放在有序列表末尾,有序列元素增加一個無序就減少一個

        # 具體的交換就是遍歷列表len(l)-1趟,沒趟都選出最小的值然後與無序列表的第一個元素交換

    程式碼:     

 1 import random
 2 l = random.sample(range(1, 100), 20)
 3 print(l)
 4 
 5 for i in range(len(l)-1):
 6     min = i
 7     for j in range(i+1, len(l)):
 8         if l[j] < l[min]:
 9             min = j
10     l[i], l[min] = l[min], l[i]
11 print(l)
View Code

 

  5、基數排序

    思想:

      # 外邊的while迴圈就是遍歷最大元素的位數,先從各位開始比較,然後遍歷陣列,把對應位數的值放在對應值編號的桶裡,即由字典包含的列表,
      # 字典的鍵就是從0到9,列表就相當於桶用來放位數值與鍵相同的元素,元素遍歷結束後就把字典所有的值都相加成一個大列表,
      # 然後再重複迴圈,整個迴圈順序:個--->十--->百---->.....,直到位數最高的元素的位數迴圈完了就結束

    程式碼:      

 1 import random
 2 
 3 arr = random.sample(range(1, 2000), 10)
 4 print(arr)
 5 
 6 d = 0
 7 while True:
 8     tag = 0
 9     bucket = {0:[], 1:[], 2:[], 3:[], 4:[], 5:[], 6:[], 7:[], 8:[], 9:[]}
10     for i in arr:
11         k = i // 10 ** d
12         tag += k
13         bucket[k % 10].append(i)
14     if tag == 0:
15         print(arr)
16         break
17     arr = []
18     for v in bucket.values():
19         arr += v
20     d += 1
21 
22 # 外邊的while迴圈就是遍歷最大元素的位數,先從各位開始比較,然後遍歷陣列,把對應位數的值放在對應值編號的桶裡,即由字典包含的列表,
23 # 字典的鍵就是從0到9,列表就相當於桶用來放位數值與鍵相同的元素,元素遍歷結束後就把字典所有的值都相加成一個大列表,
24 # 然後再重複迴圈,整個迴圈順序:個--->十--->百---->.....,直到位數最高的元素的位數迴圈完了就結束
View Code

 

  6、快速排序

    思想:

      # 每一趟都選出一個基準值,一般選取第一個為基準值,然後相當於把基準值的位置挖個坑,用兩個指標分別從最開始與最末尾移動
      # 先從最右開始,高位指標指到的值與基準值比較,如果大指標就往下走,如果比基準值小,就與坑的位置交換,高位指標此時就指到坑的位置
      # 然後低位指標從最左邊開始,低位指標指到的值與基準值比較,如果比基準值小就,就繼續往下一個走,如果比基準值大就與坑的位置交換,低位指標就指到坑的位置
      # 重複上述步驟,如果低位指標與高位指標位置重合,就終止此次趟比較,返回低位指標的位置,並把基準值賦值給低位指標
      # 然後按照低位指標的位置分割為兩個新列表,低位指標位置的值不在兩個列表之內
      # 每個列表重複上述步驟進行排序,此處使用的是遞迴實現
      # 最終終止條件是低位指標大於等於高位指標

    程式碼:     

 1 import random
 2 
 3 arr = random.sample(range(1, 101), 10)
 4 print(arr)
 5 
 6 
 7 def yitang(low, high):
 8     basevalue = arr[low]
 9     while low < high:
10         while arr[high] >= basevalue and low < high:
11             high -= 1
12         arr[low] = arr[high]
13         while arr[low] <= basevalue and low < high:
14             low += 1
15         arr[high] = arr[low]
16     arr[low] = basevalue
17     return low
18 
19 
20 def fast_sort(low, high):
21     if low < high:
22         mid = yitang(low, high)
23         fast_sort(low, mid-1)
24         fast_sort(mid+1, high)
25 
26 
27 fast_sort(0, len(arr)-1)
28 print(arr)
29 
30 # 每一趟都選出一個基準值,一般選取第一個為基準值,然後相當於把基準值的位置挖個坑,用兩個指標分別從最開始與最末尾移動
31 # 先從最右開始,高位指標指到的值與基準值比較,如果大指標就往下走,如果比基準值小,就與坑的位置交換,高位指標此時就指到坑的位置
32 # 然後低位指標從最左邊開始,低位指標指到的值與基準值比較,如果比基準值小就,就繼續往下一個走,如果比基準值大就與坑的位置交換,低位指標就指到坑的位置
33 # 重複上述步驟,如果低位指標與高位指標位置重合,就終止此次趟比較,返回低位指標的位置,並把基準值賦值給低位指標
34 # 然後按照低位指標的位置分割為兩個新列表,低位指標位置的值不在兩個列表之內
35 # 每個列表重複上述步驟進行排序,此處使用的是遞迴實現
36 # 最終終止條件是低位指標大於等於高位指標
View Code

 

  7、歸併排序

    程式碼:    

 1 import random
 2 
 3 arr = random.sample(range(1, 101), 20)
 4 print(arr)
 5 
 6 
 7 def mergeSort(arr):
 8     if len(arr) <= 1:
 9         return arr
10     num = int(len(arr) // 2)
11     left = mergeSort(arr[:num])
12     right = mergeSort(arr[num:])
13     return merge(left, right)
14 
15 
16 def merge(left, right):
17     l, r = 0, 0
18     result = []
19     while l < len(left) and r < len(right):
20         if left[l] < right[r]:
21             result.append(left[l])
22             l += 1
23         else:
24             result.append(right[r])
25             r += 1
26     result += left[l:]
27     result += right[r:]
28     return result
29 
30 
31 print(mergeSort(arr))
32 print(arr)
View Code

 

  8、堆排序

    程式碼:     

 1 import random
 2 
 3 
 4 def big_endian(arr, start, end):
 5     root = start
 6     while True:
 7         child = root * 2 + 1
 8         if child > end:
 9             break
10         if child + 1 <= end and arr[child] < arr[child + 1]:
11             child += 1
12         if arr[root] < arr[child]:
13             arr[root], arr[child] = arr[child], arr[root]
14             root = child
15         else:
16             break
17 
18 
19 def head_sort(arr):
20     first = len(arr) // 2 - 1
21     for start in range(first, -1, -1):
22         big_endian(arr, start, len(arr)-1)
23     for end in range(len(arr) - 1, 0, -1):
24         arr[0], arr[end] = arr[end], arr[0]
25         big_endian(arr, 0, end - 1)
26     return arr
27 
28 
29 def main():
30     arr = random.sample(range(1, 200), 10)
31     print(arr)
32     print(head_sort(arr))
33 
34 
35 if __name__ == '__main__':
36     main()
View Code