码迷,mamicode.com
首页 > 编程语言 > 详细

冒泡排序基本代码及其优化

时间:2015-04-03 20:47:47      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

冒泡排序基本代码及其优化

 

  冒泡排序是一种交换排序,它的基本思想是:两两比较序列中相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。它的运行过程如下(以升序排序为例):

    1.   比较相邻的元素。如果第一个比第二个大,就交换他们两个。
    2.   对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
    3.   针对所有的元素重复以上的步骤,除了最后一个。
    4.   持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

  比如待排序序列数组为:9 2 6 8 7 3 1 0 4 5,将其升序排序成序列0 1 2 3 4 5 6 7 8 9,按照上述冒泡法的运行过程有:

  9 2 6 8 7 3 1 0 4 5   相邻记录关键字作比较,9>2交换得到序列:2 9 6 8 7 3 1 0 4 5

  2 9 6 8 7 3 1 0 4 5   同样的,9>6,交换后:2 6 9 8 7 3 1 0 4 5

  2 6 9 8 7 3 1 0 4 5   9>8 交换得到:2 6 8 9 7 3 1 0 4 5

  …..

  2 6 8 7 3 1 0 4 9 5  9>5 交换 得到:2 6 8 7 3 1 0 4 5 9

  在经过N-1次比较后可以看到关键字最大的元素9经过升序冒泡后已经到了序列的最尾端,这个过程称为第一趟冒泡排序。接着再从序列的第一对相邻元素开始进行第二趟排序:

  2 6 8 7 3 1 0 4 5 9 ——>2 6 8 7 3 1 0 4 5 9

  2 6 8 7 3 1 0 4 5 9——>2 6 8 7 3 1 0 4 5 9

  2 6 8 7 3 1 0 4 5 9——>2 6 7 8 3 1 0 4 5 9

  ….

  2 6 7 3 1 0 4 8 5 9 ——>2 6 7 3 1 0 4 5 8 9

  第二趟排序完成,把关键字8升到了序列倒数第二个位置。可以发现,第二趟排序的比较次数比第一趟少了一次,8与最后的9没有进行比较。

  重复这个过程进行N-1趟的比较之后,可完成对整个序列的冒泡排序。

  按照这个思路,相应的代码为:

void BubbleSort1(int array[],int arrayLength)
{
    int i ,j ;
    for(i=0;i<arrayLength-1;++i) //进行N-1趟比较
    {
        for(j= 1;j<arrayLength-i;++j) //每趟比较中的内循环
            if(array[j]<array[j-1])  //即相邻元素之间的比较
                Swap(array[j],array[i]);  //反序,进行交换
    }
}

  注意到我在写冒泡排序定义的时候,用红色字体强调了冒泡排序进行比较的是相邻的元素,如下面这段代码,在结构上虽然很像冒泡,实际上只是简单的交换排序:

void Sort(int array[],int arrayLength)
{
    int i ,j ;
    for(i=0;i<arrayLength-1;++i) 
    {
        for(j=i+1;j<arrayLength;++j) 
            if(array[j]<array[i])  //这里比较的非相邻的元素。该算法不是冒泡
                Swap(array[j],array[i]);
    }
}

  这种算法做了大量的无用的交换操作,效率是非常低下的。

 

  排序算法还可以进行优化,设置一个标志域flag,如果某一趟排序发生了变换,那么flag为true。如果某一趟排序没有发生交换,则说明序列已经有序了,不必再进行继续的比较操作,此时flag为false。

{
    int i ,j ;
    bool flag = true;
    for(i=0;i<arrayLength-1&&flag;++i) 
    {
        flag = false;
        for(j= 1;j<arrayLength-i;++j) 
            if(array[j]<array[j-1])  
            {
                Swap(array[j],array[j-1]); 
                flag = true;  //有交换,表明当前序列尚未有序,标志为ture
            }
    }
}

 

 

  冒泡法还有另外一种优化,即只对无序的关键字进行排序。假设有序列array={2,1,5,4,0,6,7,8,9}按升序排序,则只需对无序区{2,1,5,4,0}进行排序即可。使用一个标志来记录无序区的范围:

void BubbleSort3(int array[],int arrayLength)
{
    int flag = arrayLength-1;
    while(flag>0)
    {
        for(int i = 0;i<arrayLength-1;i++)
        {
            int k = flag; 
            flag=0;
            for(int j = 0;j<k;++j)
                if(array[j]<array[j+1])
                {
                    Swap(array[j],array[j+1]);  
                    flag=j;  //记录无序区的末尾位置
                }
        }
    }
}

  当然,这种优化情况还是有点特殊的,但序列完全反序时起不到优化作用的。

 

总体来说,冒泡排序的效率是较为低下在,在数据量小的情况下可以使用,否则应该选择其他的排序算法。

 

 

冒泡排序基本代码及其优化

标签:

原文地址:http://www.cnblogs.com/QG-whz/p/4390901.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!