1.冒泡排序
思路:遍历列表,每一轮每次比较相邻两项,将无序的两项交换,下一轮遍历比前一轮比较次数减1。
- def bubble_sort(a_list):
- for passnum in range(len(a_list)-1, 0, -1):
- for i in range(passnum):
- if a_list[i] > a_list[i+1]:
- a_list[i], a_list[i+1] = a_list[i+1], a_list[i]
改进:遍历期间没有交换,则认为已排序,可以停止。
- def short_bubble_sort(a_list):
- exchanges = True
- passnum = len(a_list) - 1
- while passnum > 0 and exchanges:
- exchanges = False
- for i in range(passnum):
- if a_list[i] > a_list[i+1]:
- exchanges = True
- a_list[i], a_list[i+1] = a_list[i+1], a_list[i]
- passnum = passnum - 1
动画演示:
2.选择排序
思路:遍历列表,每次遍历选出最大的放在合适的位置。
- def selection_sort(a_list):
- for fillslot in range(len(a_list)-1, 0, -1):
- position_max=0
- for location in range(1, fillslot+1):
- if a_list[location] > a_list[position_max]:
- position_max = location
- a_list[fillslot], a_list[position_max] = a_list[position_max], a_list[fillslot]
动画演示:
3.插入排序
思路:每一步都将待插入的数据按大小插入到已排序的数据中的合适位置。
- def insertion_sort(a_list):
- for index in range(1, len(a_list)):
- cur_value = a_list[index]
- pos = index
- while pos > 0 and a_list[pos-1] > cur_value:
- a_list[pos] = a_list[pos-1]
- pos = pos - 1
- a_list[pos] = cur_value
动画演示:
4.希尔排序
思路:分解为多个子列表进行插入排序,不是连续分,而是通过增量。
- def shell_sort(a_list):
- sublist_count = len(a_list)
- while sublist_count > 0:
- for start_position in range(sublist_count):
- gap_insertion_sort(a_list, start_position, sublist_count)
- sublistcount = sublistcount // 2
-
- def gap_insertion_sort(a_list, start, gap):
- for i in range(start+gap, len(a_list), gap):
- current_value = a_list[i]
- position = i
- while position >= gap and a_list[position-gap] > current_value:
- a_list[position] = a_list[position-gap]
- position = position - gap
- a_list[position] = current_value
5.归并排序
思路:分而治之,不断拆分为一半,直至项数为0或1,然后排序合并。需要额外空间。
- def merge_sort(a_list):
- if len(a_list) > 1:
- mid = len(a_list) // 2
- lefthalf = a_list[:mid]
- righthalf = a_list[mid:]
- merge_sort(lefthalf)
- merge_sort(righthalf)
- i=0
- j=0
- k=0
- while i < len(lefthalf) and j < len(righthalf):
- if lefthalf[i] < righthalf[j]:
- a_list[k] = lefthalf[i]
- i = i + 1
- else:
- a_list[k] = righthalf[j]
- j = j + 1
- k=k+1
- while i < len(lefthalf):
- a_list[k] = lefthalf[i]
- i = i + 1
- k = k + 1
- while j < len(righthalf):
- a_list[k] = righthalf[j]
- j = j + 1
- k = k + 1
动画演示:
6.快速排序
思路:与归并一样使用分而治之,不使用额外内存,特点是枢轴值。
- def quick_sort(a_list):
- quick_sort_helper(a_list, 0, len(a_list)-1)
-
- def quick_sort_helper(a_list, first, last):
- if first < last:
- splitpoint = partition(a_list, first, last)
- quick_sort_helper(a_list, first, splitpoint-1)
- quick_sort_helper(a_list, splitpoint+1, last)
-
- def partition(a_list, first, last):
- pivotvalue = a_list[first]
- leftmark = first + 1
- rightmark = last
- done = False
- while not done:
- while leftmark <= rightmark and a_list[leftmark] <= pivotvalue:
- leftmark = leftmark + 1
- while a_list[rightmark] >= pivotvalue and rightmark >= leftmark:
- rightmark = rightmark -1
- if rightmark < leftmark:
- done = True
- else:
- a_list[leftmark], a_list[rightmark] = a_list[rightmark], a_list[leftmark]
- 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 截图