数据结构--知识点8--冒泡排序

一、排序算法的稳定性

稳定性:如果一个排序算法是稳定的,当有两个相等键值的记录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前

比如:
假设以下的数对将要以他们的第一个数字来排序
(4,1) (3,1) (3,7) (5,6)
在这个状况下,有可能产生两种不同的结果,一个是让相等键值的记录维持相对的次序,另一个则没有
维持次序:(3,1)(3,7)(4,1)(5,6)
次序被改变:(3,7)(3,1)(4,1)(5,6)
即,(3,1) 原来就在(3,7)之前,排序后(3,1)始终都在(3,7)之前为稳定的排序算法
我们比较的是3,无关于后面的7和1,如果排序后(3,1)和(3,7)顺序改变,则为不稳定算法

二、排序算法–冒泡排序

1、定义

是一种简单的排序算法
冒泡排序算法的步骤:

  • 比较相邻的元素。先比较第一个和第二个,如果第一个比第二个大,就交换这两个元素的顺序,接下来比较第二个和第三个元素……
  • 对每一对相邻的元素作同样的工作,从队列的开始到结尾。这步做完后,最后的元素会是最大的数
  • 针对所有的元素重复以上的步骤,除了最后一个(通过一个个比较得出的最大的值)
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

交换过程图示(第一次):
在这里插入图片描述

那么我们需要进行n-1次冒泡过程,直到所有的元素都轮一次

2、python实现

1)无优化

两次遍历中:
第一次为判断每个值与其他值的大小的循环;
第二次为当前值与其他值的比较的循环。
第二次在第一次的基础下,第一次循环到哪个数时,第二次的次数就是这个数之前的个数-1

def bubble_sort(alist):
    n=len(alist)
    # 共要排列多少次
    for i in range(n-1):
        # 班长从投走到尾,一次排列的循环
        for j in range(n-1-i):
            if alist[j]>alist[j+1]:
                alist[j],alist[j+1]=alist[j+1],alist[j]

if __name__ == '__main__':
    list=[44,54,73,23,1,2,53,67,88,32,21]
    print(list)
    bubble_sort(list)
    print(list)

结果:

[44, 54, 73, 23, 1, 2, 53, 67, 88, 32, 21]
[1, 2, 21, 23, 32, 44, 53, 54, 67, 73, 88]
时间复杂度
  • 最优时间复杂度:O(n)(表示遍历一次发现没有任何可以交换的元素,排序结束)
  • 最坏时间复杂度:O(n2)
  • 稳定性:稳定

2)优化版

import time
def bubble_sort(alist):
    n=len(alist)
    # 共要排列多少次

    for i in range(n-1):
        # 班长从投走到尾,一次排列的循环
        count=0
        for j in range(n-1-i):
            if alist[j]>alist[j+1]:
                alist[j],alist[j+1]=alist[j+1],alist[j]
                count += 1
        if 0 == count:
            # 添加一个count,需要交换时,也就是两个数的顺序不满足条件时,+1
            # 当count为0时表示前面的元素都是满足顺序的,没有经过交换
            # 因此在后续的循环中不再需要作比较
            return


if __name__ == '__main__':
    
    list=[44,54,73,23,1,2,53,67,88,32,21]
    print(list)
    bubble_sort(list)
    print(list)
  

结果:

[44, 54, 73, 23, 1, 2, 53, 67, 88, 32, 21]
[1, 2, 21, 23, 32, 44, 53, 54, 67, 73, 88]
时间复杂度

此时,如果出现最优复杂度的序列时,就不会再按照代码每个元素都遍历

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值