关于冒泡排序

来源:互联网 发布:cyberduck mac 破解版 编辑:程序博客网 时间:2024/05/18 21:43

大家一起学习,如果大家有什么意见或者建议可以与博主一起分享!

很多人不知道什么叫冒泡排序,我举个例子:假如有10个数{5,2,6,9,3,1,0,7,8,4}现在是乱序排放的,如何将他遍历完成之后就变成从大到小或者从小到大的排序方式呢?

首先,通过第一个数与第二个数进行比较,如果第一个数比第二个数大则交换位置,就像5比2大。那么第一个数上升,第二个数下降,这样的排序方式称为“冒泡”。

交换位置之后变成{2,5,6,9,3,1,0,7,8,4},然后再取第二个数与第三个数进行比较,即5和6进行比较,如果发现5没有大于6,那么就不交换位置。接着第三个数与第四个数进行比较,即6和9进行比较仍旧是不交换位置。

接着是第四个数与第五个数进行比较,即9和3进行比较,发现9大于3则交换位置,此时数组排序变成了{2,5,6,3,9,1,0,7,8,4}。

以此类推,9和1交换,9与0交换,9与7交换,9与8交换,9与4交换。

经过第一轮的排序后得到的数组顺序为{2,5,6,3,1,0,7,8,4,9}。

这样做的目的是为了确定数组中最大的数字——9,能够“浮”到数组的顶端。

现在开始第二轮排序,仍旧是第一个数字与第二个数字进行比较。

2与5不交换,5与6不交换,6与3交换,6与1交换,6与0交换,6与7不交换,7与8不交换,8与4交换。

经过第二轮的排序后得到的数组顺序为{2,5,3,1,0,6,7,4,8,9}

这样使得数组中第二大的数字——8,能够浮上去。

现在开始第三轮排序:

2与5不交换,5与3交换,5与1交换,5与0交换,5与6不交换,6与7不交换,7与4交换。

经过第三轮的排序后得到的数组顺序为{2,3,1,0,5,6,4,7,8,9},这样7也就“浮”上去了。

现在开始第四轮排序:

2与3不交换,3与1交换,3与0交换,3与5不交换,5与6不交换,6与4交换。

经过第四轮的排序后得到的数组顺序为{2,1,0,3,5,4,6,7,8,9},完成对6的排序。

现在开始第五轮排序:

2与1交换,2与0交换,2与3不交换,3与5不交换,5与4交换。

经过第五轮的排序后得到的数组顺序为{1,0,2,3,4,5,6,7,8,9},完成对4、5的排序

现在开始第六轮的排序:

1与0交换,1与2不交换,2与3不交换,3与4不交换。

经过第六轮的排序后得到的数组顺序为{0,1,2,3,4,5,6,7,8,9},即数组所有数已经按从小到大的顺序排好。

这个是冒泡排序的全部过程,如果从小到大的排序看懂了,从大到小相信你自己能够做出来。

现在开始将整个排序过程转化为代码的形式,博主在这里将提供C语言和JAVA以作参考。

首先在这个排序中我们用到了多次循环,不知道有没有注意到,我们刚刚的例子对10个数进行了排序,但是貌似只进行了六轮排序就完成了,很多人因此很难找到他们规律。其实我们举的例子存在着偶然性,有的时候不需要进行完全的遍历就能够将数组排序完成,例如同样是3个数字进行排序{2,1,3}只要一轮排序就能完成,而{3,2,1}则需要两轮排序才能完成。因此我们刚刚举的例子其实是不全面的。

想要以最复杂的程度对数组进行排序,将所有的可能性考虑进去,其实我们不难发现,要对3个数字进行排序,至少要进行两轮排序,要对10个数字进行排序,至少要进行九轮排序,要对N个数字进行排序,至少要进行N-1轮的排序。

很多人不明白为啥少了一轮排序,其实纵观整个排序过程,第一轮我们将数组中最大的数字排到了末尾,第二轮我们将数组中第二大的数字排到了第二的位置,那么一直到最后一轮的时候剩下的这个数字一定是最小的数字,我们没必要对它进行排序,因为它与后面的数比较一定是小于的根本不会交换位置,所以这一轮我们可以把它给舍弃掉。

当然你也可以把它算进去,10个数排十轮,N个数排N轮表面上看不出来,但是计算机在运行的时候确实会再把它比较一遍。新手只要搞懂这里的关系就行,老程序员则需要考虑程序的精简性节约计算机的运行成本。

那么由此我们可以得出冒泡排序的整个大循环——有N个数就要进行N-1次循环。

for(i=0;i<N-1;i++)

接着我们找它的第二个规律,在第一轮循环中我们进行了九次两两比较,第一个数与第二个数比较,第二个数与第三个数比较,……,第九个数与第十个数比较。这样将最大的数字9排到了最后。

而在第二轮循环中我们只进行了八次两两比较,第一个数与第二个数比较,第二个数与第三个数比较,……,第八个数与第九个比较。这样将第二大的数字8排好了。

这样我们不难发现:如果数组有N个数字,那么第一轮排序只需要进行N-1次两两比较,往后的每轮排序都比上一轮排序少一次两两比较。

同样的,这个少的比较次数其实是我们人为简化过后的,因为第一轮已经排好的数字已经是整个数组中最大的数字,在第二轮的时候没必要再去与第一轮已经排好的数字进行比较,往后的几轮同理,这属于多余比较。如果你依旧让电脑每一轮都进行N-1次比较也是没有问题的,新手需要明白这里为什么进行了简化,而老程序员则需要考虑到电脑运行的成本。

由此我们可以得出一个冒泡循环每一轮循环中需要进行的比较次数:

for(j=0;j<N-1-i;j++)

那么总体的循环思想已经表达出来了,剩下的只有两两交换位置了,现在贴出C语言的代码。

#include<stdio.h>#define N 10      //全局变量int main(){    int i,j;    int a[N]={5,2,6,9,3,1,0,7,8,4};   //直接定义了一个数组,同学们可以试着改写一下变成自己输入数字    for(i=0;i<N-1;i++)                //最外层的循环,进行了几轮排序    {        for(j=0;j<N-1-i;j++)          //里层循环,每轮排序进行了几次两两比较            if(a[j]>a[j+1])            {                int temp=0;                temp=a[j];                a[j]=a[j+1];                a[j+1]=temp;            }    }                           for(i=0;i<N;i++)                 //将排序好的数组输出    printf("%d ",a[i]);}

JAVA版本

public class test {    public static void main(String[] args)     {        int[] a = { 5, 2, 6, 9, 3, 1, 0, 7, 8, 4 };        int temp = 0;        for (int i = 0; i < a.length - 1; i++)         {            for (int j = 0; j < a.length - 1 - i; j++)             {                if (a[j] > a[j + 1])                 {                    temp = a[j + 1];                    a[j + 1] = a[j];                    a[j] = temp;                }            }        }        for (int i = 0; i < a.length; i++)            System.out.print(a[i]);    }}

好了,冒泡排序就到这了,新同学看完之后可以试着编一下从大到小,以及自己输入数组中的数字来提高自己。

有什么意见或者建议可以在下方留言,有什么看不懂得地方可以私聊博主。

原创粉丝点击