1. 程式人生 > >超炫的6種排序演算法的Python實現

超炫的6種排序演算法的Python實現

1.氣泡排序

思路:遍歷列表,每一輪每次比較相鄰兩項,將無序的兩項交換,下一輪遍歷比前一輪比較次數減1。


    
  1. def bubble_sort(a_list):
  2. for passnum in range(len(a_list) -1, 0, -1
    ):
  3. for i in range(passnum):
  4. if a_list[i] > a_list[i+ 1]:
  5. a_list[i], a_list[i+ 1
    ] = a_list[i+ 1], a_list[i]

改進:遍歷期間沒有交換,則認為已排序,可以停止。


    
  1. def short_bubble_sort(a_list):
  2. exchanges = True
  3. passnum = len(a_list) - 1
  4. while passnum > 0 and exchanges:
  5. exchanges = False
  6. for i in range(passnum):
  7. if a_list[i] > a_list[i+ 1]:
  8. exchanges = True
  9. a_list[i], a_list[i+ 1] = a_list[i+ 1], a_list[i]
  10. passnum = passnum - 1

動畫演示:

2.選擇排序

思路:遍歷列表,每次遍歷選出最大的放在合適的位置。


    
  1. def selection_sort(a_list):
  2. for fillslot in range(len(a_list) -1, 0, -1):
  3. position_max= 0
  4. for location in range( 1, fillslot+ 1):
  5. if a_list[location] > a_list[position_max]:
  6. position_max = location
  7. a_list[fillslot], a_list[position_max] = a_list[position_max], a_list[fillslot]

動畫演示:

3.插入排序

思路:每一步都將待插入的資料按大小插入到已排序的資料中的合適位置。


    
  1. def insertion_sort(a_list):
  2. for index in range( 1, len(a_list)):
  3. cur_value = a_list[index]
  4. pos = index
  5. while pos > 0 and a_list[pos -1] > cur_value:
  6. a_list[pos] = a_list[pos -1]
  7. pos = pos - 1
  8. a_list[pos] = cur_value

動畫演示:

4.希爾排序

思路:分解為多個子列表進行插入排序,不是連續分,而是通過增量。


    
  1. def shell_sort(a_list):
  2. sublist_count = len(a_list)
  3. while sublist_count > 0:
  4. for start_position in range(sublist_count):
  5. gap_insertion_sort(a_list, start_position, sublist_count)
  6. sublistcount = sublistcount // 2
  7. def gap_insertion_sort(a_list, start, gap):
  8. for i in range(start+gap, len(a_list), gap):
  9. current_value = a_list[i]
  10. position = i
  11. while position >= gap and a_list[position-gap] > current_value:
  12. a_list[position] = a_list[position-gap]
  13. position = position - gap
  14. a_list[position] = current_value

5.歸併排序

思路:分而治之,不斷拆分為一半,直至項數為0或1,然後排序合併。需要額外空間。


    
  1. def merge_sort(a_list):
  2. if len(a_list) > 1:
  3. mid = len(a_list) // 2
  4. lefthalf = a_list[:mid]
  5. righthalf = a_list[mid:]
  6. merge_sort(lefthalf)
  7. merge_sort(righthalf)
  8. i= 0
  9. j= 0
  10. k= 0
  11. while i < len(lefthalf) and j < len(righthalf):
  12. if lefthalf[i] < righthalf[j]:
  13. a_list[k] = lefthalf[i]
  14. i = i + 1
  15. else:
  16. a_list[k] = righthalf[j]
  17. j = j + 1
  18. k=k+ 1
  19. while i < len(lefthalf):
  20. a_list[k] = lefthalf[i]
  21. i = i + 1
  22. k = k + 1
  23. while j < len(righthalf):
  24. a_list[k] = righthalf[j]
  25. j = j + 1
  26. k = k + 1

動畫演示:

6.快速排序

思路:與歸併一樣使用分而治之,不使用額外記憶體,特點是樞軸值。


    
  1. def quick_sort(a_list):
  2. quick_sort_helper(a_list, 0, len(a_list) -1)
  3. def quick_sort_helper(a_list, first, last):
  4. if first < last:
  5. splitpoint = partition(a_list, first, last)
  6. quick_sort_helper(a_list, first, splitpoint -1)
  7. quick_sort_helper(a_list, splitpoint+ 1, last)
  8. def partition(a_list, first, last):
  9. pivotvalue = a_list[first]
  10. leftmark = first + 1
  11. rightmark = last
  12. done = False
  13. while not done:
  14. while leftmark <= rightmark and a_list[leftmark] <= pivotvalue:
  15. leftmark = leftmark + 1
  16. while a_list[rightmark] >= pivotvalue and rightmark >= leftmark:
  17. rightmark = rightmark -1
  18. if rightmark < leftmark:
  19. done = True
  20. else:
  21. a_list[leftmark], a_list[rightmark] = a_list[rightmark], a_list[leftmark]
  22. a_list[first], a_list[rightmark] = a_list[rightmark], a_list[first]

動畫演示:

說明:

1.參考https://interactivepython.org/runestone/static/pythonds/SortSearch/toctree.html

2.動畫來自https://visualgo.net/en 截圖

1.氣泡排序

思路:遍歷列表,每一輪每次比較相鄰兩項,將無序的兩項交換,下一輪遍歷比前一輪比較次數減1。


  
  1. def bubble_sort(a_list):
  2. for passnum in range(len(a_list) -1, 0, -1):
  3. for i in range(passnum):
  4. if a_list[i] > a_list[i+ 1]:
  5. a_list[i], a_list[i+ 1] = a_list[i+ 1], a_list[i]

改進:遍歷期間沒有交換,則認為已排序,可以停止。


  
  1. def short_bubble_sort(a_list):
  2. exchanges = True
  3. passnum = len(a_list) - 1
  4. while passnum > 0 and exchanges:
  5. exchanges = False
  6. for i in range(passnum):
  7. if a_list[i] > a_list[i+ 1]:
  8. exchanges = True
  9. a_list[i], a_list[i+ 1] = a_list[i+ 1], a_list[i]
  10. passnum = passnum - 1

動畫演示:

2.選擇排序

思路:遍歷列表,每次遍歷選出最大的放在合適的位置。


  
  1. def selection_sort(a_list):
  2. for fillslot in range(len(a_list) -1, 0, -1):
  3. position_max= 0
  4. for location in range( 1, fillslot+ 1):
  5. if a_list[location] > a_list[position_max]:
  6. position_max = location
  7. a_list[fillslot], a_list[position_max] = a_list[position_max], a_list[fillslot]

動畫演示:

3.插入排序

思路:每一步都將待插入的資料按大小插入到已排序的資料中的合適位置。


  
  1. def insertion_sort(a_list):
  2. for index in range( 1, len(a_list)):
  3. cur_value = a_list[index]
  4. pos = index
  5. while pos > 0 and a_list[pos -1] > cur_value:
  6. a_list[pos] = a_list[pos -1]
  7. pos = pos - 1
  8. a_list[pos] = cur_value

動畫演示:

4.希爾排序

思路:分解為多個子列表進行插入排序,不是連續分,而是通過增量。


  
  1. def shell_sort(a_list):
  2. sublist_count = len(a_list)
  3. while sublist_count > 0:
  4. for start_position in range(sublist_count):
  5. gap_insertion_sort(a_list, start_position, sublist_count)
  6. sublistcount = sublistcount // 2
  7. def gap_insertion_sort(a_list, start, gap):
  8. for i in range(start+gap, len(a_list), gap):
  9. current_value = a_list[i]
  10. position = i
  11. while position >= gap and a_list[position-gap] > current_value:
  12. a_list[position] = a_list[position-gap]
  13. position = position - gap
  14. a_list[position] = current_value

5.歸併排序

思路:分而治之,不斷拆分為一半,直至項數為0或1,然後排序合併。需要額外空間。


  
  1. def merge_sort(a_list):
  2. if len(a_list) > 1:
  3. mid = len(a_list) // 2
  4. lefthalf = a_list[:mid]
  5. righthalf = a_list[mid:]
  6. merge_sort(lefthalf)
  7. merge_sort(righthalf)
  8. i= 0
  9. j= 0
  10. k= 0
  11. while i < len(lefthalf) and j < len(righthalf):
  12. if lefthalf[i] < righthalf[j]:
  13. a_list[k] = lefthalf[i]
  14. i = i + 1
  15. else:
  16. a_list[k] = righthalf[j]
  17. j = j + 1
  18. k=k+ 1
  19. while i < len(lefthalf):
  20. a_list[k] = lefthalf[i]
  21. i = i + 1
  22. k = k + 1
  23. while j < len(righthalf):
  24. a_list[k] = righthalf[j]
  25. j = j + 1
  26. k = k + 1

動畫演示:

6.快速排序

思路:與歸併一樣使用分而治之,不使用額外記憶體,特點是樞軸值。


  
  1. def quick_sort(a_list):
  2. quick_sort_helper(a_list, 0, len(a_list) -1)
  3. def quick_sort_helper(a_list, first, last):
  4. if first < last:
  5. splitpoint = partition(a_list, first, last)
  6. quick_sort_helper(a_list, first, splitpoint -1)
  7. quick_sort_helper(a_list, splitpoint+ 1, last)
  8. def partition(a_list, first, last):
  9. pivotvalue = a_list[first]
  10. leftmark = first + 1
  11. rightmark = last
  12. done = False
  13. while not done:
  14. while leftmark <= rightmark and a_list[leftmark] <= pivotvalue:
  15. leftmark = leftmark + 1
  16. while a_list[rightmark] >= pivotvalue and rightmark >= leftmark:
  17. rightmark = rightmark -1
  18. if rightmark < leftmark:
  19. done = True
  20. else:
  21. a_list[leftmark], a_list[rightmark] = a_list[rightmark], a_list[leftmark]
  22. a_list[first], a_list[rightmark] = a_list[rightmark], a_list[first]