冒泡排序的基本思想:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
关于程序中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; }
程序运行结果截图:
排序——冒泡排序(三种方法)
时间: 2024-11-03 00:51:40