目录
一、排序介绍
二、冒泡排序
三、选择排序
四、插入排序
五、总结
排序目的就是将一组无序的记录序列调为有序的记录序列
列表排序:将无序列表变为有序列表
分为升序和降序
python的内置排序函数:sort()
常用的排序算法:
排序Low B三人组:冒泡排序、选择排序、插入排序
排序NB三人组: 快速排序、堆排序、归并排序
其他排序:希尔排序、计数排序、基数排序
这篇文章先来介绍排序的Low B三人组
思想:列表每两个相邻的数,如果前面比后面大,则交换这两个数 一趟排序完成后,则无序区减少一个数,有序区增加一个数
def bubble_sort(li):
for i in range(len(li)-1):
exchange = False # 改进:加一个标志位,如果经过一趟,没有发生任何交换,则说明列表已经排好序了
for j in range(len(li)-i-1):
if li[j] > li[j+1]:
# li[j] < li[j+1] 降序,li[j] > li[j+1] 升序
li[j], li[j+1] = li[j+1], li[j] # 交换两个数
exchange = True
print(li)
if not exchange:
return
测试:
# 使用列表生成式,生成一个长度为100,在0-100之间的随机列表
# li = [random.randint(0, 100) for i in range(10)]
li = [9, 8, 1, 2, 3, 4, 5, 6, 7]
print(li)
bubble_sort(li)
简单选择排序
def select_sort_simple(li):
# 缺点:多占一倍内存且复杂度高,O(n^2)
li_new = []
for i in range(len(li)):
min_val = min(li) # 复杂度O(n)
li_new.append(min_val)
li.remove(min_val) # 复杂度O(n)
return li_new
高级选择排序
def select_sort(li):
"""复杂度O(n^2)"""
for i in range(len(li)-1):
mm = i # 认为当前最小元素小标就是i
for j in range(i+1, len(li)):
if li[j] < li[mm]:
# 如果后面有还要比li[mm]小的元素,就让最小元素下标改为这个元素
mm = j
li[i], li[mm] = li[mm], li[i]
print(li)
测试:
li = [2,6,3,5,8,4,9,7]
# print(select_sort_simple(li))
select_sort(li)
思路:每次摸一张牌,插到手里已有牌的正确位置
时间复杂度:O(n^2)
# 由小到大排序
def insert_sort(li):
for i in range(1, len(li)):
# i表示当前摸到牌的下标
j = i-1 # j代表当前手里最后一张牌的下标
tem = li[i] # 用一个tem先存放当前摸到的牌,因为后面会将其覆盖掉
while j >= 0 and li[j] > tem:
li[j+1] = li[j]
j -= 1
li[j+1] = tem
print(li)
测试:
list_01 = [3, 5, 1, 6, 4, 9, 2]
print(list_01)
insert_sort(list_01)
这三大排序的时间复杂度为O(n^2),且均为原地排序
可以通过检查算法效率来验证
定义一个大小为10000的列表:list01 = list(range(10000)),用random.shuffle(list01)生成乱序列表
使用@cal_time装饰器检测函数运行时间,经检测,冒泡排序如果是对大小为10000无序列表进行排序,大概需要10秒左右,所以对于一些对算法效率要求较高的排序工作,不宜使用这三种排序算法。