演算法-排序-1.氣泡排序/2.選擇排序/3.插入排序
阿新 • • 發佈:2018-12-28
1.氣泡排序:列表每兩個相鄰的數,如果前面比後面大,則交換這兩個數
一趟排序完成後,則無序區減少一個數,有序區增加一個數
程式碼關鍵點:趟,無序區範圍
第0趟,無序區沒有數
第1趟,無序區1個數
無序去範圍:
第i趟,無序區有n-i個數,無序區範圍為n-i-1(從0開始,指標不會指到最後一個數)
程式碼如下:
1 # 時間複雜度:O(n*n) 2 def bubble_sort(li): 3 for i in range(len(li)-1): # 第i趟 4 for j in range(len(li)-i-1): #bubble_sort無序區範圍,指標最多走到的位置 5 if li[j] > li[j+1]: 6 li[j],li[j+1] = li[j+1],li[j] 7 print(li) 8 9 li = [3,9,7,2,4,6,5,8] 10 print(li) 11 bubble_sort(li)
優化方法:如果在一趟結束後沒有任何數變化,則可以結束掉接下來的迴圈
1 def bubble_sort(li): 2 for i in range(len(li)-1): #optimize_bubble_sort第i趟 3 exchange = False 4 for j in range(len(li)-i-1): # 無序區範圍,指標最多走到的位置 5 if li[j] > li[j+1]: 6 li[j],li[j+1] = li[j+1],li[j] 7 exchange = True 8 print(li) 9 if not exchange: 10 return 11 12 13 li = [3,9,7,2,4,6,5,8]14 print(li) 15 bubble_sort(li)
2.選擇排序:
方法一:
迴圈一個列表從中找到最小的數,然後將這個數新增到一個空列表中,最後將這個數從原列表中剔除掉
缺點:
1.增加了一個新列表,需要更多的記憶體
2.min和remove時間複雜度都是O(n),最後的時間複雜度是O(n*n)
程式碼如下:
1 def select_sort_simple(li): 2 li_new = [] 3 for i in range(len(li)): 4 min_val = min(li) 5 li_new.append(min_val) 6 li.remove(min_val) 7 return li_new 8 9 li = [3, 9, 7, 2, 4, 6, 5, 8] 10 print(select_sort_simple(li))select_sort_simple
方法二:
1.一趟排序記錄最小的數,放到第一個位置
2.在一趟排序記錄列表無序區最小的數,放到第二個位置
......
3.演算法關鍵點:有序區和無序區,無序區最小數的位置
程式碼如下:
1 def select_sort(li): 2 for i in range(len(li)-1): # 第i趟,最後一個數不需要選擇了 3 min_loc = i # 把無序區第一個數當做最小的數來標記 4 for j in range(i,len(li)): 5 if li[j] < li[min_loc]: 6 min_loc = j 7 li[i],li[min_loc] = li[min_loc],li[i] # 將無序區第一個數換成最小的數 8 print(li) 9 10 li = [3, 9, 7, 2, 4, 6, 5, 8] 11 print(li) 12 select_sort(li)select_sort
3.插入排序:
初始時手裡(有序區)只有一張牌
每次(從無序區)摸一張牌,插入到手裡已有牌的正確位置
當有序區的數比摸到的牌大的時候並且有序區的下標不小於0的時候,將有序區的牌往後挪個位置
時間複雜度:O(n*n)
程式碼如下:
1 def insert_sort(li): 2 for i in range(1,len(li)): # i 表示摸到的牌的下標 3 temp = li[i] 4 j = i - 1 # j 指的是手裡的牌的下標 5 while j >= 0 and li[j] > temp: 6 li[j+1] = li[j] 7 j -= 1 # 指標往前移 8 li[j+1] = temp 9 print(li) 10 11 li = [3, 9, 7, 2, 4, 6, 5, 8] 12 print(li) 13 insert_sort(li)insert_sort