软考-软件设计师:排序算法-交换类排序:冒泡排序

介绍

通过 相邻元素之间的比较和交换,按照前小后大或者前大后小规则交换。

由于整个排序的过程元素就像水底下的气泡一样逐渐向上冒,因此称为冒泡算法。

  1. 第1趟:第1个元素(左侧元素)与第2个元素(右侧元素)比较,大则交换(右侧是大的元素)
    第2与第3个比较,大则交换,依次类推
    如此操作,最后一个元素就是最大值

  2. 第2趟:以此类推,完成排序

  3. 第n趟,完成排序

例子

待排序数组:3,9,-1,10,20,进行升序排序

第一轮排序

(1)3,9,-1,10,20 ——3跟9比较,不交换

(2)3,-1,9,10,20 ——9比 -1大,所以9跟 -1交换

(3)3,-1,9,10,20 ——9跟10比较,不交换

(4)3,-1,9,10,20 ——10跟20比较,不交换

第一轮过后,将20这个最大的元素固定到了最后的位置

第二轮排序

因为20的位置已经固定,所以只对前4个进行排序即可:

(1)-1,3,9,10,20 ——3比 -1大,进行交换

(2)-1,3,9,10,20 ——3跟9比较,不交换

(3)-1,3,9,10,20 ——9跟10比较,不交换

第二轮过后,将第二大的元素固定到了倒数第二个位置

第三轮排序

10和20的位置已经确定,只需对前三个进行排序

(1)-1,3,9,10,20 ——3和-1比较,不交换

(2)-1,3,9,10,20 ——3和9比较,不交换

第三轮过后,将第三大的元素位置确定

第四轮排序

只对前两个元素进行排序

(1)-1,3,9,10,20 ——3和-1比较,不交换

第四轮过后,将第四大的元素位置确定,此时总共5个元素,已经排序好4个,从而最后一个自然而然就是排好序的了

原文链接:
https://blog.csdn.net/k_kuo_k/article/details/111650681

时间复杂度

O(n²)

解释:n个元素,每次比较 n 个元素(实际上不到n),共比较 n-1 次(最后一次必须要比较),所以总共需要 n (n-1),渐进法表示:O(n²)

时间复杂度-最好情况

O(n)
例子:

待排序数组:-1,3,9,10,20,进行升序排序

(1)-1,3,9,10,20 —— -1跟3比较,不交换

(2)-1,3,9,10,20 ——3跟9比较,不交换

(3)-1,3,9,10,20 ——9跟10比较,不交换

(4)-1,3,9,10,20 ——10跟20比较,不交换

优化:发现在某趟排序中,没有发生一次交换, 可以提前结束冒泡排序

时间复杂度-最坏情况

数组完全逆序(如 [9,8,6,3,2,1]),需要执行 n-1 趟,每趟需要 n-1-i 次比较和交换,总操作次数约为 n²/2,按大 O 规则简化为 O(n²)

空间复杂度

O(1)

算法稳定性

稳定

应用场景

适合 基本有序,如果发现在某趟排序中,没有发生一次交换, 可以 提前结束

时间复杂度:O(n)

代码实现

java实现

public class BubbleSort {
    // 冒泡排序基础方法:传入int数组,直接原地排序
    public static void bubbleSort(int[] arr) {
        // 空数组或单元素数组,无需排序,直接返回
        if (arr == null || arr.length <= 1) {
            return;
        }
        int n = arr.length;
        // 外层循环:控制冒泡趟数,最多执行 n-1 趟
        // 因为每趟确定1个最大值,n-1趟后最后1个元素自然有序
        for (int i = 0; i < n - 1; i++) {
            // 内层循环:控制每趟的相邻比较,只处理「未排序部分」
            // 后i个元素已经是排好序的最大值,无需再比较,所以结束条件是 n-1-i
            for (int j = 0; j < n - 1 - i; j++) {
                // 相邻元素比较:前一个 > 后一个,执行交换
                if (arr[j] > arr[j + 1]) {
                    // Java中交换两个数,需要临时变量
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    // 测试用例:主方法运行验证排序效果
    public static void main(String[] args) {
        // 待排序数组
        int[] arr = {6, 3, 8, 2, 9, 1};
        System.out.print("排序前的数组:");
        printArray(arr); // 打印原数组

        bubbleSort(arr); // 执行冒泡排序

        System.out.print("排序后的数组:");
        printArray(arr); // 打印排序后数组
    }

    // 辅助方法:打印数组元素,方便查看结果
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

python实现

def bubble_sort(arr):
    # 复制原数组,避免修改原数据(可选,根据需求决定)
    arr = arr.copy()
    n = len(arr)
    # 外层循环:控制冒泡的趟数,最多n-1趟
    for i in range(n - 1):
        # 内层循环:控制每一趟的相邻比较,只处理前n-1-i个元素(后i个已排序)
        for j in range(n - 1 - i):
            # 相邻比较,前一个>后一个则交换
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

# 测试代码
if __name__ == "__main__":
    test_arr = [6, 3, 8, 2, 9, 1]
    sorted_arr = bubble_sort(test_arr)
    print("原数组:", test_arr)
    print("排序后:", sorted_arr)  # 输出:[1, 2, 3, 6, 8, 9]

题

对n个数排序,最坏情况下时间复杂度最低的算法是()排序算法。

A、插入
B、冒泡
C、归并
D、快速

分析

插入排序,最坏的情况,时间复杂度是 O(n²)
冒泡排序,最坏的情况,时间复杂度是 O(n²)
归并排序,最坏的情况,时间复杂度是 O(nlog₂n)
快速排序,最坏的情况,时间复杂度是 O(n²)

复杂度 最低 的算法,也就是 效率最高


原文出处:/show_1GWwqG5vju8.html