数据结构与算法Python版 冒泡排序与选择排序


一、冒泡排序

冒泡排序Bubble Sort

  • 对无序表进行多趟比较交换,每趟包括了多次两两相邻比较,并将逆序的数据项互换位置,最终能将本趟的最大项就位
  • 经过n-1趟比较交换,实现整表排序。每趟的过程类似于“气泡”在水中不断上浮到水面
    • 第1趟比较交换,共有n-1对相邻数据进行比较,一旦经过最大项,则最大项会一路交换到达最后
      一项
    • 第2趟比较交换时,最大项已经就位,需要排序的数据减少为n-1,共有n-2对相邻数据进行比较
    • 直到第n-1趟完成后,最小项一定在列表首位,就无需再处理了。

示例:冒泡排序第1趟

在这里插入图片描述

def bubble_sort(lst):
    for pass_num in range(len(lst) - 1, 0, -1):  # n-1趟
        for j in range(pass_num):
            if lst[j] > lst[j + 1]:
                # 错序,进行交换
                lst[j], lst[j + 1] = lst[j + 1], lst[j]


test_list = [18, 48, 85, 67, 44, 36, 53, 32, 3, 5]
bubble_sort(test_list)
print(test_list)


### 输出结果
[3, 5, 18, 32, 36, 44, 48, 53, 67, 85]

冒泡排序-算法分析

  • 算法过程总需要n-1趟,随着趟数的增加,比对次数逐步从n-1减少到1,并包括可能发生的数据项交换
  • 比对次数是1~n-1的累加:1/2*n^2+1/2*n。比对的时间复杂度是O(n2);交换次数,时间复杂度也是O(n2)。
  • 冒泡排序通常作为时间效率较差的排序算法,来作为其它算法的对比基准。但它无需任何额外的存储空间开销。

冒泡排序-改进

  • 如果某趟比对没有发生任何交换,说明列表已经排好序,可以提前结束算法
def bubble_sort_plus(lst):
    for pass_num in range(len(lst) - 1, 0, -1):
        exchanges = False
        for j in range(pass_num):
            if lst[j] > lst[j + 1]:
                lst[j], lst[j + 1] = lst[j + 1], lst[j]
                exchanges = True # 发生交换

        # 如果某趟没有交换,提前结束
        if exchanges == False:
            return

二、选择排序

选择排序Selection Sort

  • 对冒泡排序改进交换次数,变成选择排序
  • 选择排序对交换进行了削减,相比起冒泡排序进行多次交换,每趟记录最大项的所在位置,最后再跟本趟最后一项交换
  • 选择排序的时间复杂度比冒泡排序稍优。比对次数不变,还是O(n^2);交换次数则减少为O(n)
def selection_sort(lst):
    for pass_num in range(len(lst) - 1, 0, -1):
        max_item_idx = 0
        for j in range(pass_num):
            if lst[j + 1] > lst[max_item_idx]:
                max_item_idx = j + 1
        lst[pass_num], lst[max_item_idx] = lst[max_item_idx], lst[pass_num]


test_list = [18, 48, 85, 67, 44, 36, 53, 32, 3, 5]
selection_sort(test_list)
print(test_list)


### 输出结果
[3, 5, 18, 32, 36, 44, 48, 53, 67, 85]

在这里插入图片描述

参考资料:数据结构与算法可视化网站


您正在阅读的是《数据结构与算法Python版》专栏!关注不迷路~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值