排序算法之冒泡排序

冒泡排序(Bubble Sort),是一种比较排序算法,它通过重复遍历数列,比对和交换错误顺序的相邻元素实现对数列的排序。

原理


假设被排序数组 a 的长度为 n,冒泡排序首先比对尾部相邻元素 a[n-1]a[n-2](假设数组索引从 0 开始),如果它们的顺序错误,则交换它们。之后,比较 a[n-2]a[n-3] 并在顺序错误时交换它们,以此类推,直到 a[0] 被比对,此时最小(或最大)的数值被确定在 a[0] 位置。

此时,冒泡排序再次从 a[n-1]a[n-2] 开始比对,如果它们的顺序错误,则交换它们,直到 a[1] 被比对,此时数列中第二小(或第二大)的数值被确定在 a[1] 位置。循环执行上述操作,直至 a[n-2] 位置的数值被确认,则数列完成排序。

综上,冒泡排序的操作步骤如下:

  1. 从尾部元素开始比较相邻两元素,若尾部元素小于相邻元素,则交换两元素位置。
  2. 向前对每对相邻元素做同样的比对和交换操作,从尾部第一对到头部最后一对,完成后,头部元素将成为数列中最小的元素。
  3. 重新从尾部开始做第 1、2 步操作,除去每次重复之前数列头部已排序的元素。
  4. 重复上述操作,直至没有任何一对元素需要比较。

以数列 (6, 2, 3, 1, 8) 为例,冒泡排序的执行过程如下所示:

第一次遍历:

(6, 2, 3, 1, 8) -> (6, 2, 3, 1, 8)
(6, 2, 3, 1, 8) -> (6, 2, 1, 3, 8)
(6, 2, 1, 3, 8) -> (6, 1, 2, 3, 8)
( 6, 1, 2, 3, 8) -> ( 1, 6, 2, 3, 8)

第二次遍历:

(1, 6, 2, 3, 8) -> (1, 6, 2, 3, 8)
(1, 6, 2, 3, 8) -> (1, 6, 2, 3, 8)
(1, 6, 2, 3, 8) -> (1, 2, 6, 3, 8)

第三次遍历:

(1, 2, 6, 3, 8) -> (1, 2, 6, 3, 8)
(1, 2, 6, 3, 8) -> (1, 2, 3, 6, 8)

第四次遍历:

(1, 2, 3, 6, 8) -> (1, 2, 3, 6, 8)

实现


冒泡排序 Python 实现代码:

def bubbleSort(nums):
    n = len(nums)
    for i in range(1, n):
        swapped = False
        for j in range(n - 1, i - 1, -1):
            if nums[j] < nums[j - 1]:
                nums[j], nums[j - 1] = nums[j - 1], nums[j]
                swapped = True
        if swapped == False:
            break
    return nums

性能


根据冒泡排序的实现逻辑可知,外层循环执行 n − 1 n-1 n1 次,内层循环执行 ( n − 1 ) − ( i − 1 ) = n − i (n-1)-(i-1) = n-i (n1)(i1)=ni 次,比较和交换操作为常数级 O ( 1 ) O(1) O(1)。因此,冒泡排序的时间复杂度可通过下式计算:

∑ i = 1 n − 1 ∑ j = i n − 1 1 = ∑ i = 1 n − 1 ( n − i ) = ( n − 1 ) + ( n − 2 ) + . . . + 1 = n ( n − 1 ) 2 \begin{aligned} \sum_{i=1}^{n-1}\sum_{j=i}^{n-1}1 &= \sum_{i=1}^{n-1}(n-i) \\ &= (n-1) + (n-2) + ... + 1 \\ &= \frac{n(n-1)}{2} \end{aligned} i=1n1j=in11=i=1n1(ni)=(n1)+(n2)+...+1=2n(n1)

因此,冒泡排序在最坏情况与平均情况下的时间复杂度均为 O ( n 2 ) O(n^2) O(n2),在最好情况下,数组有序,时间复杂度为 O ( n ) O(n) O(n)

空间复杂度方面,冒泡排序只需固定数量的额外空间用于存储数组长度、索引值和临时变量,所以空间复杂度为 O ( 1 ) O(1) O(1)

稳定性方面,冒泡排序只有在相邻元素值不相等且顺序错误时才对元素的位置进行调整,值相等元素的相对顺序不会发生变化,因此,冒泡排序是稳定的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值