博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
排序算法-冒泡排序
阅读量:4881 次
发布时间:2019-06-11

本文共 3096 字,大约阅读时间需要 10 分钟。

算法简介

冒泡排序(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;        }    }

转载于:https://www.cnblogs.com/wupeixuan/p/8654026.html

你可能感兴趣的文章
edgeR
查看>>
Android开发学习一:环境搭建
查看>>
入门容易深入难
查看>>
20155228 你期望的师生关系是什么?
查看>>
unreal slate 创建 window
查看>>
《从零開始学Swift》学习笔记(Day 52)——Cocoa错误处理模式
查看>>
[Buzz Today]2013.02.12
查看>>
struts1学习笔记二
查看>>
c++
查看>>
计算100~200之间不能被3整除的数,continue使用范例
查看>>
计算三个数的平均值
查看>>
基于visual c++之windows核心编程代码分析(34)WinIo驱动级模拟按键的实现
查看>>
使用WSAIoctl获取AcceptEx函数指针 [转]
查看>>
【图论补完计划】poj 3613(Floyd 快速幂)
查看>>
JAX-RS -- Java API for RESTful Web Services
查看>>
Android Handler消息传递机制
查看>>
[BZOJ1572] WorkScheduling
查看>>
Struts2学习笔记1--Struts2简介
查看>>
Redis面试总结
查看>>
CSS3 2D转换
查看>>