【常见排序算法】
1.冒泡排序——Bubble Sort
复杂度 O(n^2)
【思路】
1.列表每两个相邻的数,如果前面比后面大,则交换这两个数
2.一趟排序完成后,则无序区减少一个数,有序区增加一个数
3.代码关键点:趟、无序区范围(第i趟 n-i-1)
4.整个冒泡排序应该是(n-1)趟 (从0开始)但最后一趟无序区只剩下最后一个数
一定是最大或最小值,所以是len(n)-1趟
【代码】
import random #导入随机模块
#冒泡排序
def bubble_sort(li):
for i in range(len(li)-1):#一共要执行的趟数(每趟生成一个有序的数)
for j in range(len(li)-1-i):#(无序区)每一趟里从底往上一层层比较大小
#将'>'改为'<',交换列表排列顺序
if li[j]>li[j+1]: #前一项大于后一项,交换位置()
li[j],li[j+1]=li[j+1],li[j]
print(li)
#randint 随机整数,生成(0,100)的数
li=[random.randint(0,100) for i in range(10)]#列表生成式
print(li)
bubble_sort(li)
print(li)
【结果】
可以观察到一共是九趟,但是最后三项是重复的,已经排完序,所以我们需要进行优化
如果一趟冒泡排序中没有进行交换,可以认为这个列表已经排完序
【优化冒泡排序】
import random #导入随机模块
#冒泡排序
def bubble_sort(li):
for i in range(len(li)-1):#一共要执行的趟数(每趟生成一个有序的数)
exchange=False #每一趟加个标志位
for j in range(len(li)-1-i):
if li[j]>li[j+1]: #前一项大于后一项,交换位置()
li[j],li[j+1]=li[j+1],li[j]
exchange=True #标记一下
if exchange==False:#if not exchange:
return
print(li)
li=[9,8,7,6,1,2,3,4,5]#列表生成式
print(li)
bubble_sort(li)
【优化前】
【优化后】
2.选择排序——Select Sort
复杂度 O(n^2)
【思路】
1.一趟排序记录最小的数,放在第一个位置
2.再一趟排序记录记录无序区最小的数,放在第二个位置
。。。
3.算法关键点:有序区和无序区、无序区最小数的位置
【代码】
#选择排序
def select_sort(li):
#最大趟数是n-1趟,记录到最后,无序区还剩一个数,一定是最大的,所以不需要再走一趟,所以再-1
for i in range(len(li)-1):
min_i=i #存放i的下标
for j in range(i+1,len(li)):#遍历i后面的数
if li[j]<li[min_i]: #如果li[j]比i小,存放j的下标
min_i=j
li[i],li[min_i]=li[min_i],li[i] #循环一次,将最小值存入第一位
print(li)
li=[9,8,7,6,1,2,3,4,5]
print(li)
select_sort(li)
【结论】
3.插入排序
复杂度 O(n^2)
【思路】
1.初始时是一个数字
2.每次添加一个数,插入到相应位置,
【例题】
1.用j来储存已经添加的数的下标,然后要存放6,首先将6提取出来,定义tmp,遍历循环
2.此时j是7,则将j往右挪一位 li[j+1]=li[j]
3.将下标j-1,判断5 和 6
4.此时j是5,比6小,所以将6的下标存放在5的右面,即li[j+1]=tmp
【详细代码实现】
#插入排序
def insert_sort(li):
for i in range(1,len(li)): #表示要加进来的数的下标,li[0]用于判断
tmp=li[i] #将下标i的值储存起来
j=i-1 #目前已经加入的数的下标
#两个条件:下标j等于-1推出循环;下标j的值大于加入的数的值,否则推出循环
while j>=0 and li[j]>tmp:
li[j+1]=li[j] #li[j+1]的值已经被tmp存起来了,所以当li[j]>tmp,向右挪一
j-=1 #当j减到-1时,即最左边时,li[0]=tmp
li[j+1]=tmp #将tmp的值放在相应位置
print(li)
li=[9,8,7,6,1,2,3,4,5]
print(li)
insert_sort(li)
【运行结果】