列表排序方法——冒泡|选择|插入——python

列表排序算法——LowB三人组

冒泡排序

  • 列表每两个相邻的数,如果前面比后面大(升序),则交换这两个数

  • 一趟排序完成后,则无序区减少一个数,有序区增加一个数
    ![[b2de9c82d158ccbf4555f4b015d8bc3eb035414a.gif]]

  • 进行下一趟时,对整个无序区进行排列

  • 代码关键点:趟、无序区范围

def bubble_sort(li):  
    for i in range(len(li)-1):          # 第i趟  ->  n-1趟
 		for j in range(len(li)-i-1):    # 无序范围  ->  [0, n-i-1]
            if li[j]>li[j+1]:  
                a=li[j]  
                li[j]=li[j+1]  
                li[j+1]=a  
    return li
  • 时间复杂度 O( n 2 n^{2} n2)

缺点

当无序区已经排序好之后,冒泡排序依旧会走剩下的几趟
比如如果有序列 lst=[9,8,7,1,2,3,4,5,6]
执行代码

def bubble_sort(li):  
    for i in range(len(li)-1):   # 第i趟  
 		print(li)  
        for j in range(len(li)-i-1):  
            if li[j] > li[j+1]:  
                a=li[j]  
                li[j]=li[j+1]  
                li[j+1]=a  
    print(li)  
  
lst = [9,8,7,1,2,3,4,5,6]  
bubble_sort(lst)



'''
输出结果为
排序前:
[9, 8, 7, 1, 2, 3, 4, 5, 6]
排序过程:
[8, 7, 1, 2, 3, 4, 5, 6, 9]
[7, 1, 2, 3, 4, 5, 6, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
实际上排序三趟就已经排完了
'''

∴ \therefore 如果在一趟过程中没有进行交换,则后续无需进行

改进

加一个标志位 exchange

def bubble_sort(li):  
    for i in range(len(li)-1):   # 第i趟  
 exchange = False  
 print(li)  
        for j in range(len(li)-i-1):  
            if li[j] > li[j+1]:  
                a = li[j]  
                li[j] = li[j+1]  
                li[j+1] = a  
                exchange = True  
 if exchange == False:  
            break  
 print(li)  
  
lst = [9,8,7,1,2,3,4,5,6]  
bubble_sort(lst)


'''
输出为
排序前:
[9, 8, 7, 1, 2, 3, 4, 5, 6]
排序过程:
[8, 7, 1, 2, 3, 4, 5, 6, 9]
[7, 1, 2, 3, 4, 5, 6, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
'''

选择排序

先从列表中遍历一遍是否可以找到一个最小的数,并拿出来,再在剩下的元素中遍历······

def select_sort(li):  
    li_new=[]  
    for i in range(len(li)):    # 需要遍历n遍  
 min_val = min(li)  
        li_new.append(min_val)  
        li.remove(min_val)  
    return li_new  
  
  
lst = [1, 2, 5, 6, 7, 3, 2, 4]  
print(select_sort(lst))

不推荐上述写法,因为

  • 新建了一个列表,数据量大
  • 复杂度高, ∵ \because remove、 min都不是 O ( 1 ) O(1) O(1)的操作

优化

找到最小的数和第一个数交换

def select_sort(li):  
    for i in range(len(li)-1):  
        min_loc = i  
        for j in range(i+1, len(li)):      # 无序区范围  
 			if li[j] < li[min_loc]:  
                min_loc = j  
        a = li[i]  
 		li[i] = li[min_loc]  
		li[min_loc] = a    				   # li[i] li[min_loc]做交换  
 	return li  
  
  
lst = [1, 2, 5, 6, 7, 3, 2, 4]  
print(select_sort(lst))

插入排序

类似于打牌前理牌
从无序区抽牌插到有序区
![[20200806234248667.gif]]

  • 要摸多少次排——n-1
  • 每次摸一张
  • 比较大小,决定是否挪牌
def insert_sort(li):  
    for i in range(1, len(li)):       # i表示摸到的牌的下标  
 	j = i-1                           # j指的是手里的最后一张牌  
	while li[j] > li[j+1]:  
            a = li[j]  
            li[j] = li[j+1]  
            li[j+1] = a               # 交换两位  
            j = j-1                   
 			if j == -1:  
                break  
 	print(li)  
  
  
lst = [1, 2, 5, 6, 7, 3, 2, 4]  
insert_sort(lst)

时间复杂度 O ( n 2 ) O(n^{2}) O(n2)

  • 24
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值