• 排序算法-冒泡排序


    算法简介

    冒泡排序(Bubble Sort)是一种典型的交换排序算法,持续比较相邻元素,大的挪到后面,因此大的会逐步往后挪,故称之为冒泡。

    算法描述

    • 比较相邻的元素。如果第一个比第二个大(小),就交换它们两个;
    • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大(小)的数;
    • 针对所有的元素重复以上的步骤,除了最后一个;
    • 重复步骤1~3,直到排序完成。

    冒泡

    代码实现

        /**
         * 冒泡排序
         *
         * @param array
         */
        private static void bubbleSort(int[] array) {
            if (array == null || array.length == 0 || array.length == 1)
                return;
            for (int i = 0; i < array.length - 1; i++) {
                for (int j = 0; j < array.length - 1 - i; j++) {//注意数组边界
                    if (array[j] > array[j + 1]) {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
        }
    

    性能分析

    最好情况下:正序有序,则只需要比较$n$次。故为$O(n)$。

    最坏情况下:逆序有序,则需要比较 $(n-1)+(n-2)+……+1$,故为$O(n^2)$。

    当原始序列杂乱无序时,冒泡排序的平均时间复杂度为$O(n^2) $。

    因为需要一个临时变量来交换元素位置,(另外遍历序列时自然少不了用一个变量来做索引),所以其空间复杂度为$O(1)$。

    冒泡排序在排序过程中,元素两两交换时,相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

    排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 稳定性
    冒泡排序 $O(n^2)$ $O(n)$ $O(n^2)$ $O(1)$ 稳定

    冒泡排序优化(优化外层循环)

    若在某一趟排序中未发现位置的交换,则说明待排序的无序区中所有元素均有序,因此,冒泡排序过程可在此趟排序后终止。为此,在下面给出的算法中,引入一个标签flag,在每趟排序开始前,先将其置为false。若排序过程中发生了交换,则将其置为true。各趟排序结束时检查flag,若未曾发生过交换则终止算法,不再进行下一趟排序。

        /**
         * 冒泡优化(外层循环优化)
         *
         * @param array
         */
        private static void bubbleSort_2(int[] array) {
            if (array == null || array.length == 0 || array.length == 1)
                return;
            boolean flag = true;//发生了交换就为true, 没发生就为false,第一次判断时必须标志位true
            for (int i = 0; i < array.length - 1; i++) {
                flag = false;//每次开始排序前,都设置flag为未排序过
                for (int j = 0; j < array.length - 1 - i; j++) {//注意数组边界
                    if (array[j] > array[j + 1]) {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                        flag = true;//表示交换过数据;
                    }
                }
                //判断标志位是否为false,如果为false,说明后面的元素已经有序,就直接return
                if (flag == false)
                    return;
            }
        }
    

    冒泡排序优化(优化内层循环)

    在每趟扫描中,记住最后一次交换发生的位置pos,(该位置之后的相邻记录均已有序)。下一趟排序开始时,$array[1,pos-1]$是无序区,$array[pos,n]$是有序区。故在进行下一趟排序时只要扫描到pos位置即可。

        /**
         * 冒泡优化(内层循环优化)
         *
         * @param array
         */
        private static void bubbleSort_3(int[] array) {
            if (array == null || array.length == 0 || array.length == 1)
                return;
            boolean flag = true;//发生了交换就为true, 没发生就为false,第一次判断时必须标志位true
            int k = array.length - 1;
            int pos = 0;//pos变量用来标记循环里最后一次交换的位置
            for (int i = 0; i < array.length - 1; i++) {
                flag = false;//每次开始排序前,都设置flag为未排序过
                for (int j = 0; j < k; j++) {//注意数组边界
                    if (array[j] > array[j + 1]) {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                        flag = true;//表示交换过数据;
                        pos = j;
                    }
                }
                k = pos;
                //判断标志位是否为false,如果为false,说明后面的元素已经有序,就直接return
                if (flag == false)
                    return;
            }
        }
    
  • 相关阅读:
    从程序员到项目经理(24):怎样给领导汇报工作
    从程序员到项目经理(22):对绩效考核的吐槽
    从程序员到项目经理(23):项目管理不能浑水摸鱼
    从程序员到项目经理(21):以德服人才能口服心服
    从程序员到项目经理(19):让员工为目标而干活
    从程序员到项目经理(20):谁都需要成就感
    从程序员到项目经理(18):想改变任何人都是徒劳的
    从程序员到项目经理(17):不要试图和下属做朋友
    从程序员到项目经理(16):你不是一个人在战斗--思维一换天地宽
    [SQL] 不合并重复数据 union all
  • 原文地址:https://www.cnblogs.com/wupeixuan/p/8654026.html
Copyright © 2020-2023  润新知