
writer:lIcht email:lIcht.gzl@gmail.com Date: 2019.9.15
排序方法的是对数据处理必不可少的算法,主要的排序方法有冒泡排序、选择排序、插入排序、shell排序、快速排序、归并排序等。根据待处理的数据结构不同选择不同的排序方法不同处理数据的效率也会不同。排序方法的好坏可以用最坏时间复杂度以及最优时间复杂度来衡量。
xxxxxxxxxx# 冒泡排序# 最坏时间复杂度O(n^2)# 最优时间复杂度O(n)# 稳定def bubble_sort(alist): """冒泡排序""" for j in range(1, len(alist)): count = 0 for i in range(0, (len(alist)-j)): # 从头走到尾 if alist[i] > alist[i+1]: alist[i], alist[i+1] = alist[i+1], alist[i] count += 1 if count == 0: # 如果一次循环后没有任何元素交换(顺序已正确)则停止排序 returnif __name__ == "__main__": li = [54, 26, 93, 17, 31, 55, 65, 30] print(li) bubble_sort(li) print(li)
xxxxxxxxxx# 选择排序# 最坏时间复杂度O(n^2)# 最优时间复杂度O(n^2)# 不稳定def select_sort(alist): """选择排序""" for j in range(len(alist)-2): min = j for i in range(j+1, len(alist)): if alist[min] > alist[i]: min = i alist[j], alist[min] = alist[min], alist[j]if __name__ == "__main__": li = [54, 26, 93, 17, 31, 55, 65, 30] print(li) select_sort(li) print(li)
xxxxxxxxxx# 插入排序# 最坏时间复杂度O(n^2)# 最优时间复杂度O(n)# 稳定def insert_sort(alist): """插入排序""" for j in range(1, len(alist)): i = j while i > 0: # for i in range(j, 0, -1) i取值为[j, j-1, ..., 0] (range中 "-1" 参数为反向顺序取值) if alist[i] < alist[i-1]: alist[i], alist[i-1] = alist[i-1], alist[i] i -= 1 else: # 优化,提升了最优时间复杂度 breakif __name__ == "__main__": li = [54, 26, 93, 17, 31, 55, 65, 30] print(li) insert_sort(li) print(li)
xxxxxxxxxx# 希尔排序# 最坏时间复杂度O(n^2)# 最优时间复杂度,根据步长不同而不同# 不稳定def shell_sort(alist): """希尔排序""" n = len(alist) gap = n//2 # gap变化到0之前插入算法执行的次数 while gap > 0: # 插入算法。与普通插入算法区别就是gap步长 for j in range(gap, n): i = j while i > 0: if alist[i] < alist[i-gap]: alist[i], alist[i - gap] = alist[i - gap], alist[i] i -= gap else: break # 缩短gap步长 gap //= 2if __name__ == "__main__": li = [54, 26, 93, 17, 31, 55, 65, 30] print(li) shell_sort(li) print(li)
xxxxxxxxxx# 快速排序(必须掌握)# 最坏时间复杂度O(n^2)# 最优时间复杂度O(nlogn)# 不稳定def quick_sort(alist, first, last): """快速排序""" if first >= last: return mid_value = alist[first] low = first high = last while low < high: # high 左移动 while low < high and alist[high] >= mid_value: high -= 1 alist[low] = alist[high] # low 右移动 while low < high and alist[low] < mid_value: low += 1 alist[high] = alist[low] # 退出循环时 low=high alist[low] = mid_value # 递归方式对原有列表mid_value两边的两部分进行处理 quick_sort(alist, 0, low-1) quick_sort(alist, low+1, 0)if __name__ == "__main__": li = [54, 26, 93, 17, 31, 55, 65, 30] print(li) quick_sort(li, 0, len(li)-1) print(li)
xxxxxxxxxx# 归并排序# 最坏时间复杂度O(nlogn)# 最优时间复杂度O(nlogn)# 稳定def merge_sort(alist): """归并排序""" n = len(alist) if n <= 1: return alist mid = n//2 # left right是采用归并排序后形成的新的有序列表 left_li = merge_sort(alist[:mid]) right_li = merge_sort(alist[mid:]) # 将两个有序的子序列合并为一个新的整体 left_pointer, right_pointer = 0, 0 result = [] while left_pointer < len(left_li) and right_pointer < len(right_li): if left_li[left_pointer] < right_li[right_pointer]: result.append(left_li[left_pointer]) left_pointer += 1 else: result.append(right_li[right_pointer]) right_pointer += 1 result += left_li[left_pointer:] result += right_li[right_pointer:] return resultif __name__ == "__main__": li = [54, 26, 93, 17, 31, 55, 65, 30] print(li) sorted_li = merge_sort(li) print(sorted_li)