1. 程式人生 > >演算法-排序-1.氣泡排序/2.選擇排序/3.插入排序

演算法-排序-1.氣泡排序/2.選擇排序/3.插入排序

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): #
無序區範圍,指標最多走到的位置 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)
bubble_sort

  優化方法:如果在一趟結束後沒有任何數變化,則可以結束掉接下來的迴圈

 1 def bubble_sort(li):
 2     for i in range(len(li)-1):  #
第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)
optimize_bubble_sort

 

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