冒泡排序的基本思想:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大 的数往下沉 ,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
关于程序中4中冒泡排序写法的说明:
bubble_sort1:基本的冒泡排序的写法。
bubble_sort2:基本冒泡排序的不同写法,基本的冒泡排序是每次遍历,每次缩小范围1,这种办法是每次正向和反向遍历,每次缩小范围2,所以两者的比较次数也是一样的。
bubble_sort3:如果在某一趟的冒泡途中没有出现数据交换,那就只能是数据已经被排好序了,这样就可以提前得知数据排好序从而中断循环,消除掉不必要的比较。
bubble_sort4:如果在某一趟的冒泡途中最后的交换出现在pos的位置,那么表示pos位置以后都已经排好序,这样相比于基本冒泡每一次缩小遍历范围1而言有可能一次缩小的遍历范围>=1,所以这样也可以提高排序的效率。
程序代码如下:
这里写代码片
#include <stdio.h>
int bubble_sort1(int num[], int n) /*最基本的冒泡排序法*/
{
int i, j, tmp;
int count = 0;
for(i = 0; i < n-1; i++) /*冒泡一次放好一个数,冒泡n-1次就可以全部放置好*/
for(j = 0; j < n-1-i; j++, count++) /*后面的i个数已经为有序序列*/
{
if(num[j] > num[j+1])
{
tmp = num[j];
num[j] = num[j+1];
num[j+1] = tmp;
}
}
return count;
}
int bubble_sort2( int num[], int n) /*基本冒泡法的另一种写法*/
{
int low = 0;
int high= n -1; /*设置边界low和high*/
int tmp, j, count = 0;
while (low < high)
{
for(j=low; j < high; j++, count++) /*正向冒泡,找最大值*/
if (num[j] > num[j+1])
{
tmp = num[j];
num[j] = num[j+1];
num[j+1] = tmp;
}
high --; /*更新冒泡区间*/
for(j=high; j > low; j--, count++) /*反向冒泡,找最小值*/
if (num[j] < num[j-1])
{
tmp = num[j];
num[j] = num[j-1];
num[j-1] = tmp;
}
low ++; /*更新冒泡区间*/
}
return count;
}
int bubble_sort3(int num[], int n) /*加入一标志性变量exchange,用于标志某一趟排序过程中是否有数据交换,
如果进行某一趟排序时并没有进行数据交换,则说明数据已经按要求排列好,
则立即结束排序,避免不必要的比较过程。*/
{
int i, j, tmp, exchange = 1, count =0;
for(i = 0; i<n-1 && (exchange==1); i++) /*判断上一趟是否有数据交换,没有则表明排序已完成*/
for(j = 0, exchange=0; j < n-1-i; j++, count++)
{
if(num[j] > num[j+1])
{
exchange = 1;
tmp = num[j];
num[j] = num[j+1];
num[j+1] = tmp;
}
}
return count;
}
int bubble_sort4(int num[], int n) /*加入一标志性变量pos,用于标志某一趟排序过程中最后交换数据的位置,
那么在这个位置之后的数据都是已经排好序的,进而根据这个pos重新计算
还剩余的冒泡次数*/
{
int i, j, tmp, pos, count =0;
for(i=0; i < n-1; i=n-pos) /*n-pos表示已经排好序的个数,用来替代以前的i++方式计算已经排好序的个数*/
for(j=0, pos=0; j < n-1-i; j++, count++) /*pos=0是必须的,不然没有交换的时候会出现死循环*/
{
if(num[j] > num[j+1])
{
tmp = num[j];
num[j] = num[j+1];
num[j+1] = tmp;
pos = j+1; /*从j+1开始的往后的数据已经排好序*/
}
}
return count;
}
void print_num(int num[], int n)
{
int i;
printf("[0-%d]: ", n-1);
for(i=0; i < n; i++)
printf("%d ", num[i]);
printf("\n");
}
int main()
{
int num1[] = {1, 9, 3, 5, 6, 2, 7, 10, 8, 4, 11, 15, 13, 12, 16, 14};
int num2[] = {1, 9, 3, 5, 6, 2, 7, 10, 8, 4, 11, 15, 13, 12, 16, 14};
int num3[] = {1, 9, 3, 5, 6, 2, 7, 10, 8, 4, 11, 15, 13, 12, 16, 14};
int num4[] = {1, 9, 3, 5, 6, 2, 7, 10, 8, 4, 11, 15, 13, 12, 16, 14};
int cmp_cnt;
cmp_cnt = bubble_sort1(num1, sizeof(num1)/sizeof(int));
print_num(num1, sizeof(num1)/sizeof(int));
printf("Method1 compare count is: %d.\n\n", cmp_cnt);
cmp_cnt = bubble_sort2(num2, sizeof(num2)/sizeof(int));
print_num(num2, sizeof(num2)/sizeof(int));
printf("Method2 compare count is: %d.\n\n", cmp_cnt);
cmp_cnt = bubble_sort3(num3, sizeof(num3)/sizeof(int));
print_num(num3, sizeof(num3)/sizeof(int));
printf("Method3 compare count is: %d.\n\n", cmp_cnt);
cmp_cnt = bubble_sort4(num4, sizeof(num4)/sizeof(int));
print_num(num4, sizeof(num4)/sizeof(int));
printf("Method4 compare count is: %d.\n\n", cmp_cnt);
return 0;
}
程序运行结果截图:
冒泡排序法的特点:
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定