冒泡排序及其改进


冒泡排序作为最经典的算法,虽然对大数据无用武之地。但是对于少量的数据,我们用冒泡排序,在时间复杂度上也是可以接受的,又因为它实现起来比较简单,所以也经常的被人们使用。并且可以通过一些方法来改进最原始的冒泡排序,这种改进算法的思路也有可取之处。

前一两天参加宜搜科技的笔试,就考到了冒泡排序。我当时就想写一个改进之后的算法。还是稍稍的考虑了一下的。所以现在整理一下,希望下次会更加的熟练。

冒泡排序的思路非常的简单,即将相邻的两个数相比较,将较大的数向后移动。我们可以知道每一次都会有一个大数沉底。

下面我们来看最简单的冒泡排序:

void swap(int *a,int *b)
{
 int temp=*a;
 *a=*b;
 *b=temp;
}

 

//未改进的冒泡排序,其时间复杂度为O(n*n)
void bubble1(int a[],int n)
{
 for(int i=0;i<n;i++)
  for(int j=1;j<n-i;j++)
   if(a[j-1]>a[j])
    swap(a[j-1],a[j]);

}

我们稍微的思考一下,就可以找到一种改进方法。如果在一趟排序中没有数据发生交换,那不就是说,数据已经有序了吗。据此很容易写出以下的代码:

void bubble2(int a[],int n)
{
 int k=n;
 bool flag=true;
 while(flag)
 {
  flag=false;
  for(int i=1;i<k;i++)
  {
   if(a[i-1]>a[i]){
    swap(a[i-1],a[i]);
    flag=true;
   }
  }
  k--;
 }
}

还能改进吗?我们可以通过记录每趟发生交换的最后位置(后面的都已经有序了),来缩小需要比较的数组长度。据此,容易写出以下的代码:

//在这个基础之上还是继续改进算法的
//我们可以通过记录每一趟排序最后发生交换的位置来缩小比较数组的大小
//这样,虽然改进比较小,但是思路非常的巧妙
void bubble3(int a[],int n)
{
 int flag=n;
 int k;
 while(flag>0)
 {
  k=flag;
  //将flag置零,这样是为了使程序能够安全的跳出,而非死循环
  flag=0;
  for(int i=1;i<k;i++)
  {
   if(a[i-1]>a[i])
    swap(a[i-1],a[i]);
   flag=i;
  }
 }
}

 

void printArray(int a[],int n)
{
 for(int i=0;i<n;i++)
  cout<<a[i]<<" ";
 cout<<endl;
}

好了,这时这些了。如果大家有更好的方法或者思路,不吝指教。

PHP 冒泡排序法

经典排序之冒泡排序

Python实现冒泡排序法

Go语言实现冒泡排序

C++ 使用模板实现冒泡排序

Java简单排序之冒泡排序代码

冒泡排序优化版,性能近乎翻倍

本文永久更新链接地址:

相关内容