0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一文了解冒泡排序

算法与数据结构 2018-01-17 12:47 次阅读

要点

冒泡排序是一种交换排序。

什么是交换排序呢?

交换排序:两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。

算法思想

它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名。

假设有一个大小为 N 的无序序列。冒泡排序就是要每趟排序过程中通过两两比较,找到第 i 个小(大)的元素,将其往上排。

一文了解冒泡排序

以上图为例,演示一下冒泡排序的实际流程:

假设有一个无序序列 { 4. 3. 1. 2, 5 }

第一趟排序:通过两两比较,找到第一小的数值 1 ,将其放在序列的第一位。

第二趟排序:通过两两比较,找到第二小的数值 2 ,将其放在序列的第二位。

第三趟排序:通过两两比较,找到第三小的数值 3 ,将其放在序列的第三位。

至此,所有元素已经有序,排序结束。

要将以上流程转化为代码,我们需要像机器一样去思考,不然编译器可看不懂。

假设要对一个大小为 N 的无序序列进行升序排序(即从小到大)。

(1) 每趟排序过程中需要通过比较找到第 i 个小的元素。

所以,我们需要一个外部循环,从数组首端(下标 0) 开始,一直扫描到倒数第二个元素(即下标 N - 2) ,剩下最后一个元素,必然为最大。

(2) 假设是第 i 趟排序,可知,前 i-1 个元素已经有序。现在要找第 i 个元素,只需从数组末端开始,扫描到第 i 个元素,将它们两两比较即可。

所以,需要一个内部循环,从数组末端开始(下标 N - 1),扫描到 (下标 i + 1)。

核心代码

publicvoidbubbleSort(int[]list){

inttemp=0;// 用来交换的临时数

// 要遍历的次数

for(inti=0;i< list.length - 1;i++){

// 从后向前依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上

for(intj=list.length-1;j>i;j--){

// 比较相邻的元素,如果前面的数大于后面的数,则交换

if(list[j-1]>list[j]){

temp=list[j-1];

list[j-1]=list[j];

list[j]=temp;

}

}

System.out.format("第 %d 趟: ",i);

printAll(list);

}

}

冒泡排序算法的性能

一文了解冒泡排序

时间复杂度

若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值:Cmin = N - 1, Mmin = 0。所以,冒泡排序最好时间复杂度为O(N)。

若初始文件是反序的,需要进行 N -1 趟排序。每趟排序要进行 N - i 次关键字的比较(1 ≤ i ≤ N - 1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:

Cmax = N(N-1)/2 = O(N2)

Mmax = 3N(N-1)/2 = O(N2)

冒泡排序的最坏时间复杂度为O(N2)。

因此,冒泡排序的平均时间复杂度为O(N2)。

总结起来,其实就是一句话:当数据越接近正序时,冒泡排序性能越好。

算法稳定性

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。

所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

优化

对冒泡排序常见的改进方法是加入标志性变量exchange,用于标志某一趟排序过程中是否有数据交换。

如果进行某一趟排序时并没有进行数据交换,则说明所有数据已经有序,可立即结束排序,避免不必要的比较过程。

核心代码

// 对 bubbleSort 的优化算法

publicvoidbubbleSort_2(int[]list){

inttemp=0;// 用来交换的临时数

booleanbChange=false;// 交换标志

// 要遍历的次数

for(inti=0;i< list.length - 1;i++){

bChange=false;

// 从后向前依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上

for(intj=list.length-1;j>i;j--){

// 比较相邻的元素,如果前面的数大于后面的数,则交换

if(list[j-1]>list[j]){

temp=list[j-1];

list[j-1]=list[j];

list[j]=temp;

bChange=true;

}

}

// 如果标志为false,说明本轮遍历没有交换,已经是有序数列,可以结束排序

if(false==bChange)

break;

System.out.format("第 %d 趟: ",i);

printAll(list);

}

}

完整参考代码

packagenotes.javase.algorithm.sort;

importjava.util.Random;

publicclassBubbleSort{

publicvoidbubbleSort(int[]list){

inttemp=0;// 用来交换的临时数

// 要遍历的次数

for(inti=0;i< list.length - 1;i++){

// 从后向前依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上

for(intj=list.length-1;j>i;j--){

// 比较相邻的元素,如果前面的数大于后面的数,则交换

if(list[j-1]>list[j]){

temp=list[j-1];

list[j-1]=list[j];

list[j]=temp;

}

}

System.out.format("第 %d 趟: ",i);

printAll(list);

}

}

// 对 bubbleSort 的优化算法

publicvoidbubbleSort_2(int[]list){

inttemp=0;// 用来交换的临时数

booleanbChange=false;// 交换标志

// 要遍历的次数

for(inti=0;i< list.length - 1;i++){

bChange=false;

// 从后向前依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上

for(intj=list.length-1;j>i;j--){

// 比较相邻的元素,如果前面的数大于后面的数,则交换

if(list[j-1]>list[j]){

temp=list[j-1];

list[j-1]=list[j];

list[j]=temp;

bChange=true;

}

}

// 如果标志为false,说明本轮遍历没有交换,已经是有序数列,可以结束排序

if(false==bChange)

break;

System.out.format("第 %d 趟: ",i);

printAll(list);

}

}

// 打印完整序列

publicvoidprintAll(int[]list){

for(intvalue:list){

System.out.print(value+" ");

}

System.out.println();

}

publicstaticvoidmain(String[]args){

// 初始化一个随机序列

finalintMAX_SIZE=10;

int[]array=newint[MAX_SIZE];

Randomrandom=newRandom();

for(inti=0;i< MAX_SIZE;i++){

array[i]=random.nextInt(MAX_SIZE);

}

// 调用冒泡排序方法

BubbleSortbubble=newBubbleSort();

System.out.print("排序前: ");

bubble.printAll(array);

// bubble.bubbleSort(array);

bubble.bubbleSort_2(array);

System.out.print("排序后: ");

bubble.printAll(array);

}

}

运行结果

一文了解冒泡排序

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 排序
    +关注

    关注

    0

    文章

    31

    浏览量

    9661

原文标题:详解冒泡排序

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA排序-冒泡排序介绍

    排序算法是图像处理中经常使用一种算法,常见的排序算法有插入排序、希尔排序、选择排序冒泡
    发表于 07-17 10:12 667次阅读
    FPGA<b class='flag-5'>排序</b>-<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>介绍

    labview 版的冒泡排序

    labview 版的冒泡排序,只是想用Labview表达冒泡法的思想,
    发表于 06-05 11:18

    冒泡排序

    package algorithms// 冒泡排序// 冒泡排序算法的运作如下:// 比较相邻的元素。如果第个比第二个大,就交换他们两个。
    发表于 10-17 19:03

    常用排序法之 ——冒泡排序法和选择排序

    语言中,常用的算法有:冒泡排序、快速排序、插入排序、选择排序、希尔排序、堆
    发表于 11-01 12:25

    冒泡排序法三部曲の冒泡排序原理版

    的类型就多进行3x4次排序,为了解决这个问题,对冒泡排序法进行进步优化,将在冒泡
    发表于 09-12 10:30

    冒泡排序法三部曲の冒泡排序原理版()

    ;, array[n]);printf("\t");//空格次}return 0;}运行结果上述代码没有问题,但是如果数组是类似{1,2,3,5,4}这样的类型就多进行3x4次排序,为了解决这个问题,对
    发表于 09-12 10:42

    Java冒泡排序的原理是什么?

    Java冒泡排序的原理
    发表于 11-06 07:12

    冒泡排序法的具体实现方法是什么?

    什么是冒泡排序冒泡排序法的具体实现方法是什么?
    发表于 07-15 06:48

    C语言教程之冒泡排序

    C语言教程之冒泡排序,很好的C语言资料,快来学习吧。
    发表于 04-22 11:06 0次下载

    揭秘冒泡排序、交换排序和插入排序

    01 — 冒泡排序 在实现冒泡排序代码之前我们先理解一下什么是冒泡排序,我们举一个现实生活中的例
    的头像 发表于 06-18 09:57 1306次阅读

    C语言冒泡排序工程代码汇总

    C语言冒泡排序工程代码汇总
    发表于 08-30 11:06 3次下载

    冒泡排序的基本思想

    冒泡排序的英文Bubble Sort,是一种最基础的交换排序。之所以叫做冒泡排序,因为每一个元素都可以像小气泡一样,根据自身大小一点一点向数
    的头像 发表于 01-20 11:38 5203次阅读
    <b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>的基本思想

    php版冒泡排序是如何实现的?

    无论学习哪一种编程语言,进行算法方面的训练时都绕不开“排序”。排序在进阶编程中有非常广泛的应用,要想成为编程高手,排序算法是必须要掌握的。而冒泡排序
    的头像 发表于 01-20 10:39 652次阅读
    php版<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>是如何实现的?

    怎样运用Java实现冒泡排序和Arrays排序出来

    在数据结构中我们学习了解冒泡排序和Arrays排序的基本算法,但没能够用编程语言实现出来。那我们应该怎样运用Java通过编程语言将冒泡
    的头像 发表于 03-02 09:37 321次阅读
    怎样运用Java实现<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>和Arrays<b class='flag-5'>排序</b>出来

    jwt冒泡排序的原理

    jwt简介 冒泡排序: (Bubble Sort)是一种简单的交换排序。之所以叫做冒泡排序,因为我们可以把每个元素当成一个小气泡,根据气泡大
    的头像 发表于 09-25 16:33 313次阅读
    jwt<b class='flag-5'>冒泡</b><b class='flag-5'>排序</b>的原理