C++编写经典算法之一:冒泡排序BubbleSort

“冒泡排序”是数列排序的算法之一
其思路引点来源于经典的“可乐雪碧问题”

“现有两杯饮料,一杯是雪碧,一杯是可乐,试问如何可以将两杯饮料交换?”
“答:最简单的解决方案就是利用一个空杯,创造一个缓存区。”

冒泡排序就是利用不断的对比、交换数据,从而实现对数列的排序。换言之,就是不断的拿起两个数,进行比较,如果是升序排序,就把小的放在前面,同理,降序排序,就将大的放在前面,不断的有序的重复这个过程,就会将数列排序整齐,这种方法类似小孩子的思考方式,其特点就为思维简单、比较费时。

  1. 经典误区
    对于初次接触到冒泡排序的人,在大致了解到该排序方法后,心里会油然而生一种感觉—这个算法也太简单了,交换循环就完事了。实则,实践起来的时候,你就会发现:循环几次?怎么去比较?有必要有多少个数就循环几次吗?算法是一种优化思想,对于无用的重复的操作如果能避免掉,那就都要避免掉。

    试想:

    按照一个数就循环一次,不断全部比较换位的想法,如果有数列 {4 5 3 2 1} ,经过一次升序换位,就变成了 {4 5 3 2 1}->{1 4 5 3 2},这时就进行了4次比较。再来,{1 4 5 3 2}->{1 2 4 5 3}->{1 2 3 4 5},我们不难发现,到这里经过12次比较就可以对这个数列进行升序排序的完成,但,如果我们算法将其设计为简单的循环5次,那么我们就会进行20次比较,其中有8次,在做无用的比较。这是因为,冒泡排序中有个隐藏的规律:**如果是升序,进行比较换位,在一次循环后,就会将最小的数放在首位,再一次循环后,次小的就会放在第二位,以此类推…就实现了升序排序。**所以我们有必要去避免做这“8次”无用的比较,其思路很简单。

  2. 算法思路
    我们先看一下动画演示:
    在这里插入图片描述
    通过动画演示,我们不难发现,为了避免无用的比较,我们会在一次循环后将较小的数定位,并在下一次循环时不予考虑,因为实际上它已经完成了它的排序,并且,循环的次数明显也因此在减少,这才是我们平时常说的“冒泡循环”。

  3. 代码清单及测试结果

#include <iostream>
template <class T>

int getSizeOfArray(T& bs){
   return sizeof(bs)/ sizeof(bs[0]);
}

void bubbleSort(int * bs,int size){

   for(int i = 0;i<=size-1;i++){
       for(int j = size-1;j>i;j--){
           if(bs[j]<bs[j-1])
           {
               int cup = bs[j-1];
               bs[j-1] = bs[j];
               bs[j] = cup;
           }
       }
   }
}

int main() {
   using namespace std;

   int bs[] = {2,3,5,1,0,8,6,9,7};
   int size = getSizeOfArray(bs);

   cout<< "原数列:";

   for(int i = 0;i<size;i++)
   {
       cout<< bs[i] << " ";
   }

   cout<< "\n" << "冒泡排序后:";

   bubbleSort(bs,size);

   for(int i = 0;i<size;i++)
   {
       cout<< bs[i] << " ";
   }

   return 0;
}

演示结果:
在这里插入图片描述

  1. 算法分析

时间复杂度
若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数 和记录移动次数 均达到最小值: 在这里插入图片描述在这里插入图片描述
所以,冒泡排序最好的时间复杂度为 在这里插入图片描述
  若初始文件是反序的,需要进行 在这里插入图片描述 趟排序。每趟排序要进行在这里插入图片描述次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:
  在这里插入图片描述
在这里插入图片描述

冒泡排序的最坏时间复杂度为 在这里插入图片描述
综上,因此冒泡排序总的平均时间复杂度为 在这里插入图片描述

算法稳定性

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章