在开始这三种算法的学习之前,我们要先来补给几个知识:
时间复杂度:用来评估算法运行效率的一个式子
时间复杂度-小结:
快速地判断算法复杂度:
简单情况:
复杂情况:根据算法执行过程判断
相同值的情况下,排序完两个值的相对位置不会发生变化。
算法描述
比较相邻的两个元素,如果第一个比第二个大,就交换他们两个的位置。(每一趟都会冒出一个有序区的数。)
动图
代码实现
def bubble_sort(li): # 第一层循环,总共需要循环几趟 # 默认最后一躺的那个数字已经是最大or最小值,所以最后一趟不用走了(能省则省) for i in range(len(li) - 1): exchange = False # 此标志位用来检测该躺有没有发生前后值的替换,如果没有的话,说明列表已经有序,后面无需循环
# 第二层循环,就是循环比较无序区中的数字 for j in range(len(li) - i - 1): # -i(i 躺数):每一趟就会产生一个有序区的数字在最后面,我们循环只负责找无序区的数字 # -1 n个数,相邻替换的次数比len少1 if li[j + 1] > li[j]: li[j + 1], li[j] = li[j], li[j + 1] exchange = True if not exchange: return li = [1, 2, 5, 3, 4, 6, 9, 8, 7] bubble_sort(li) print(li)
##[9, 8, 7, 6, 5, 4, 3, 2, 1]
小结:
算法描述
每一趟选择一个数放在第一位,然后后面每个数都与这个数进行比较,如果比第一位数大的话就替换掉第一个数,一趟完成过后有序区产生一个有序数字,然后每一趟都循环无序区中的数字。
动图演示
代码演示
def select_sort(li): # 第一次循环,循环几趟 for i in range(len(li) - 1): # -1:每一次循环都要选择第一个数出来和后面的数进行比较 所以要-1, 比如[4, 1, 2, 3] min_sol = i # 第二层循环,无序区中每个数都与第一个数字进行比较 for j in range(i+1, len(li)): # 每次比较都是无序区中的数字,所以是 除了抽出来的数字 到最后一个数字 if li[j] > li[min_sol]: min_sol = j li[i], li[min_sol] = li[min_sol], li[i] li = [1, 2, 5, 3, 4, 6, 9, 8, 7] select_sort(li) print(li)
小结:
算法描述
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置插入。
实现思路:
动图演示
代码实现
def insert_sort(li): for i in range(1, len(li)): j = i - 1 # j 为手里最大的牌 while j >= 0 and li[j] > li[i]: # 只要手里最大的牌比摸回来的牌大就一致往右移动 # j >= 0 ,说明所有数都比摸到的牌要大,直接退出循环 li[j+1] = li[j] # 右移 j -= 1 li[j+1] = li[i] # 确定要插入的时候,是必须插到j的前一个位置
小结:
原文:https://www.cnblogs.com/Xuuuuuu/p/10804830.html