三种较low排序
主要内容
- 1.冒泡排序
- 2.选择排序
- 3.插入排序
1. 冒泡排序
时间复杂度 : O(n2)
原理:
- 比较相邻的元素,如果后一个比前一个大就进行交换
- 对每一对相邻元素做同样的工作,完成以后,最后的元素会是最大的数,这里可以理解为走了一趟;
- 针对所有的元素重复以上的步骤,除了最后一个
冒泡排序代码
import random from cal_time import cal_time @cal_time def bubble_sort(lst): for i in range(len(lst)-1): # i 表示要进行冒泡比较的趟数 # 第i趟的无序区位置 [0,n-1-i] for j in range(len(lst) -i -1): if lst[j] > lst[j+1]: #下一个数比当前的大就进行交换 lst[j],lst[j+1] = lst[j+1],lst[j] # 测试: lst = list(range(10000)) random.shuffle(lst) bubble_sort(lst) #bubble_sort running time: 7.759883880615234 secs
代码做一次优化:
@cal_time def bubble_sort(lst): for i in range(len(lst)-1): # i 表示要进行冒泡比较的趟数 # 第i趟的无序区位置 [0,n-1-i] exchange = False for j in range(len(lst) -i -1): if lst[j] > lst[j+1]: #下一个数比当前的大就进行交换 lst[j],lst[j+1] = lst[j+1],lst[j] exchange = True if not exchange: return
对于时间复杂度的具体讨论:
- 最好情况 :此时的列表已将排好序,此时无序进行交换 时间复杂度为 O(n)
- 平均情况 :此时的列表为正常的无序状态, 时间复杂度为O(n^2)
- 最坏情况 :此时列表是倒序,每次都需要进行交换 时间复杂度为O(n^2)
2. 选择排序
- 一趟遍历记录最小的数,放到第一个位置
- 再一趟遍历记录剩余列表中最小的数,继续放置
关键:
- 无序区
- 最小数的位置
def find_min(lst): min_num = lst[0] for i in range(1,len(lst)): if lst[i] < min_num: min_num = lst[i] return min_num #获取最小数的位置 def find_min_pos(lst): min_pos = 0 for j in range(1,len(lst)): if lst[j] < lst[min_pos]: min_pos = j return min_pos
代码 时间复杂度 O(n^2)
import random from cal_time import cal_time @cal_time def select_sort(lst): for i in range(len(lst) -1): #第 i趟无序区 [i,len(lst)-1] #找无序区最小数的位置,和无序区第一个数进行交换 min_pos = i for j in range(i+1,len(lst)): if lst[j] < lst[min_pos]: min_pos = j lst [min_pos],lst[i] = lst[i],lst[min_pos] li = list(range(10000)) random.shuffle(li) select_sort(li) #select_sort running time: 3.5867788791656494 secs.
3. 插入排序
- 将列表分为有序区和无序区两个部分,最初有序区只有一个元素
- 每次从无序区选择一个元素,插入到有序区的位置,知道无序区变空
import random from cal_time import cal_time @cal_time def insert_sort(lst): for i in range(1,len(lst)): # 从无序区摸排,表示第i趟,i表示摸到的牌 tmp = lst[i] # tmp表示摸到的牌的值 #摸到的牌前一张,即有序区最后一张牌的下标为j j = i - 1 while j >=0 and lst[j] > tmp: #只要往后挪就循环,2个条件都满足 #如果j =-1 就停止挪,如果lst[j]小了就停止挪 lst[j+1] = lst[j] j -=1 #j位置在循环结束的时 # 候要么是-1 要么是一个比tmp小的值的下标 lst[j+1] = tmp li = list(range(10000)) random.shuffle(li) insert_sort(li)