• 冒泡排序算法分析


    1. 基本思想

    冒泡排序的基本思想:
      对于待排序数列, 依次比较相邻元素, 若顺序相反, 则交换位置, 重复此步骤直至完成排序.

    2. 过程演示

    [5, 4, 3, 2, 1] 来演示整个排序过程

    原始序列:    5, 4, 3, 2, 1
    
    第一趟排序:  4, 5, 3, 2, 1
                4, 3, 5, 2, 1
                4, 3, 2, 5, 1
                4, 3, 2, 1, 5
    
    第二趟排序:  3, 4, 2, 1,   5
                3, 2, 4, 1,   5
                3, 2, 1, 4,   5
    
    第三趟排序:  2, 3, 1,   4, 5
                2, 1, 3,   4, 5
    
    第四趟排序:  1, 2,   3, 4, 5
    

    可以看出:
      每一趟排序都将所经过的最大的元素放在了最后的位置, 所以第 n趟排序并不需要关心倒数第 n + 1个元素.

    3. 代码实现

    // 冒泡排序
    private static int[] bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {        
            boolean swapped = false;    // 第 (i + 1)次是否发生了元素交换
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j , j + 1);
                    printArr(j, j + 1, arr);    // 打印比较过程
                    swapped = true;
                }
            }
            if (!swapped)    // 未发生元素交换的话, 表示数组已经是有序的了
                break;
        }
        return arr;
    }
    /* 
    output: 
        原始数组: [5, 4, 3, 2, 1]
        i = 0, j = 1  ---> [4, 5, 3, 2, 1]
        i = 1, j = 2  ---> [4, 3, 5, 2, 1]
        i = 2, j = 3  ---> [4, 3, 2, 5, 1]
        i = 3, j = 4  ---> [4, 3, 2, 1, 5]
        i = 0, j = 1  ---> [3, 4, 2, 1, 5]
        i = 1, j = 2  ---> [3, 2, 4, 1, 5]
        i = 2, j = 3  ---> [3, 2, 1, 4, 5]
        i = 0, j = 1  ---> [2, 3, 1, 4, 5]
        i = 1, j = 2  ---> [2, 1, 3, 4, 5]
        i = 0, j = 1  ---> [1, 2, 3, 4, 5]
        排序后: [1, 2, 3, 4, 5]
    */
    
    // 交换数组中指定索引处的元素位置
    private static void swap(int[] arr, int i, int j) {
        if (i > arr.length - 1 || i < 0 || j > arr.length - 1 || j < 0) {
            throw new RuntimeException("索引值有误");
        }
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
    
    // 打印数组元素
    private static void printArr(int[] arr) {
        System.out.println(Arrays.toString(arr));
    }
    
    // 打印 i, j的索引, 和当前数组的顺序
    private static void printArr(int i, int j, int[] arr) {
        System.out.print("i = " + i + ", j = " + j + "  ---> ");
        printArr(arr);
    }
    

    4. 复杂度分析

    假设: 给定一个含有 n个元素的序列

    最好情形:
      给定序列是正序, 那么走一趟即可完成排序, 所需比较次数C和记录移动次数M均达到最小值, 即:

    Cmin = n - 1
    Mmin = 0

    所以, 冒泡排序最好的时间复杂度是 O(n)

    最坏情形:
      给定序列是倒序, 那么需要进行 n - 1 趟排序, 第 i趟排序需要进行 n - i 次比较, 且每次比较都必须移动记录三次来达到交换位置的效果, 在这种情况下, 比较和移动次数均达到最大值.

    所以, 冒泡排序最坏的时间复杂度是 O(n^2)

    Cmax = n * (n - 1) / 2 = O(n^2)
    Mmax = 3 * n * (n - 1) / 2 = O(n^2)

    综上所述, 冒泡排序的平均时间复杂度是 O(n^2)

    5. 总结

  • 相关阅读:
    Google analytics平均页面停留时间为何是0
    用易语言拦截窗口消息(带例程)
    OS + Linux RHEL / RedHat Enterprise 5 / 6 / 6.3
    Oracle学习教程:动态SQL与游标详解
    图解Oracle数据库(二)
    Oracle数据库中listener.ora sqlnet.ora tnsnames.ora的区别
    正确理解javascript的this关键字
    深入理解Javascript之this关键字
    Oracle中动态SQL详解
    oracle维护常用SQL语句(查看系统表和视图)
  • 原文地址:https://www.cnblogs.com/bobo132/p/13950350.html
Copyright © 2020-2023  润新知