1.冒泡排序
# 优化版 优化有序的情况,最优时间复杂度O(n)
def bubble_sort(alist): # 外层循环控制比较几轮 n = len(alist) for j in range(n - 1): # 定义计数器 count = 0 # 内存循环控制交换 # -j是不再换已经排好的 for i in range(n - 1 - j): # 若前一个比后一个大,则换 if alist[i] > alist[i + 1]: alist[i], alist[i + 1] = alist[i + 1], alist[i] # 计数器 count += 1 if count == 0: return
2.选择排序
# alist = [3, 11, 26, 26,7, 3, 9, 4] # 选择排序把数据当成2部分 # alist = [3, 11, 26, 26,7, 9, 4] # alist = [3, 4 11, 26, 26,7, 9] # 怎么找到最小值? 索引min = 0 # 最终min = 0 # min = 1开始 # min = 6 # alist[1] alist[6] def select_sort(alist): n = len(alist) # 外层控制比较几轮 for j in range(n - 1): min_index = j # 内层控制元素比较和更新索引 for i in range(j + 1, n): # 进行比较 if alist[min_index] > alist[i]: # 更新索引 min_index = i # 退出循环后,交换数据 alist[j], alist[min_index] = alist[min_index], alist[j] if __name__ == '__main__': li = [3, 11, 26, 26, 7, 3, 9, 4] print(li) select_sort(li) print(li)
3.插入排序
# 插入排序 def insert_sort(alist): n = len(alist) # 外层循环控制从右边取多少元素 for j in range(1, n): # i = [1,2,3...] i = j # 内存循环 while i > 0: if alist[i] < alist[i - 1]: alist[i], alist[i - 1] = alist[i - 1], alist[i] # 控制循环结束 i -= 1 else: break if __name__ == '__main__': li = [54, 26, 93, 17, 77, 31, 44, 55, 20] print(li) insert_sort(li) print(li)
4.希尔排序
# 希尔排序 def shell_sort(alist): n = len(alist) # 假如gap = n/2 gap = n // 2 # 控制gap 不断缩小 while gap >= 1: # 插入排序 # 这里从gap开始到最后比较 for j in range(gap,n): # i = [gap,gap+1,...] 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 //= 2
5.快速排序
# 快排 # first理解为第一个位置的索引,last是最后位置索引 def quick_sort(alist, first, last): # 递归终止条件 if first >= last: return # 设置第一个元素为中间值 mid_value = alist[first] # low指向 low = first # high high = last # 只要low小于high就一直走 while low < high: # high大于中间值,则进入循环 while low < high and alist[high] >= mid_value: # high往左走 high -= 1 # 出循环后,说明high小于中间值,low指向该值 alist[low] = alist[high] # high走完了,让low走 # low小于中间值,则进入循环 while low < high and alist[low] < mid_value: # low向右走 low += 1 # 出循环后,说明low大于中间值,high指向该值 alist[high] = alist[low] # 退出整个循环后,low和high相等 # 将中间值放到中间位置 alist[low] = mid_value # 递归 # 先对左侧快排 quick_sort(alist, first, low - 1) # 对右侧快排 quick_sort(alist, low + 1, last) if __name__ == '__main__': li = [54, 26, 93, 17, 77, 31, 44, 55, 20] print(li) quick_sort(li, 0, len(li) - 1) print(li)
6.归并排序
# 归并排序 def merge_sort(alist): n = len(alist) # 递归结束条件 if n <= 1: return alist # 中间位置 mid = n // 2 # 递归拆分左侧 left_li = merge_sort(alist[:mid]) # 递归拆分右侧 right_li = merge_sort(alist[mid:]) # 需要2个游标,分别指向左列表和右列表第一个元素 left_point, right_point = 0, 0 # 定义最终返回的结果集 result = [] # 循环合并数据 while left_point < len(left_li) and right_point < len(right_li): # 谁小谁放前面 if left_li[left_point] <= right_li[right_point]: # 放进结果集 result.append(left_li[left_point]) # 游标移动 left_point += 1 else: result.append(right_li[right_point]) right_point += 1 # 退出循环时,形成左右两个序列 result += left_li[left_point:] result += right_li[right_point:] return result if __name__ == '__main__': li = [54, 26, 93, 17, 77, 31, 44, 55, 20] print(li) sort_li = merge_sort(li) print(li) print(sort_li)