排序算法之冒泡排序

        冒泡排序就是把小的元素往前调或者把大的元素往后调,即小的元素逐渐“冒泡”,较大的元素逐渐“沉底”。其中比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,则不交换;如果两个元素不相等,则需要交换。由于交换是相邻元素,则两个相等元素的前后顺序并没有发生变化,所以冒泡排序是一种稳定排序算法。
首先介绍一种类似于冒泡排序的算法,实际交换为i和j的元素,而不是j和j + 1 的元素,从而导致算法不稳定,即两个相等元素的前后顺序发生变化。
1.算法思路:
    设待排序数组为a[n],设置两个标志i和j,i表示当前比较元素,j表示逐个与i元素相比较的下标。假设交换为较小的冒泡,即i次循环结果第i个较小的元素确定。
2.举例说明:
   设数组a的元素为:1 8 4 6 9 4(*) 2  (说明:(*)是为了区别两个相等元素
   第一趟:i = 0 ;j 从1开始; 因a[i] < a[j],则j++; 其结果为:1 8 4 6 9 4(*) 2
   第二趟:i = 1;j 从2开始;a[i] = 8;a[j] = 4;因a[i] > a[j],交换为:a[i] = 4;a[j] = 8;j++;最终为:1 2 8 6 9 4(*) 4 (不稳定)
   .......
   第六趟:i = 5;结果为:1 2 4(*) 4 6 8 9
 
程序如下:
void BubbleSort(int a[],int n)
{
 int i,j;
 for(i = 0;i < n - 1;i++)
 {
  for(j = i + 1; j < n;j++)
  {
   if(a[i] > a[j])
   {
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;    
   }
  }
 }
}


 
其次给出一般冒泡排序算法的例子:
第一趟:1 8 4 6 9 4(*) 2 -> 1 4 6 84(*) 2 9
第二趟:1 4 6 8 4(*) 2 9 -> 1 4 64(*) 2 8 9
......
第六趟:1 4 2 4(*)  6 8 9 -> 1 2 4 4(*)  6 8 9
 
程序如下:
void BubbleSort2(int a[],int n)
{
 int i,j;
 for(i = 0;i < n - 1;i++)
 {
  for(j =0; j < n - i - 2;j++)
  {
   if(a[j] > a[j+1])
   {
    int temp = a[j]
    a[j] = a[j+1];
    a[j+1] = temp;    
   }
  }
 }
}

再次对于一些基本有序的可以通过查看是否有交换来终止循环。

 
程序如下:
void BubbleSort2(int a[],int n)
{
 int i,j;
 bool flag = true;
 for(i = 0;i < n - 1 && flag;i++)
 {
  flag = false;
  for(j =0; j < n - i - 2;j++)
  {
   if(a[j] > a[j+1])
   {
    int temp = a[j]
    a[j] = a[j+1];
    a[j+1] = temp;    
    flag = true;
   }
  }
 }
}

最后,其实我们可以同时从头和从尾开始比较,每次循环可以确定两个元素的位置,从而提高排序的速度。

程序如下:

void BubbleSort3(int a[],int n)
{
 int i,j;
 int k = 0;
 bool flag = true;
 while(flag)
 {
  flag = false;
  for(j = k; j < n - 2 - k;j++)
  { 
   i = n - j - 1;
   if(a[j] > a[j+1])
   {
    int temp = a[j];
    a[j] = a[j+1];
    a[j+1] = temp;   
    flag = true;
   }
   if(a[i] < a[i-1])
   {
    int temp = a[i];
    a[i] = a[i-1];
    a[i-1] = temp;   
    flag = true;
   }   
  }
  k++;
 }

}


 

总之,冒泡排序是比较简单易懂的排序算法,是需要基本掌握的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值