冒泡排序

来源:互联网 发布:linux 复制多行 编辑:程序博客网 时间:2024/06/16 19:29

冒泡排序的基本思想:

在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大 的数往下沉 ,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

关于程序中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)

稳定性:稳定

0 0
原创粉丝点击