在C语言中,常用的排序算法有:冒泡排序、快速排序、插入排序、选择排序、希尔排序、堆排序以及归并排序等等. 

  冒泡排序基本概念:  依次比较相邻的两个数,将小数放在前面,大数放在后面。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <time.h>
 4 
 5 #define MAXSIZE 4
 6 
 7 typedef struct {
 8     int r[MAXSIZE]; 
 9     int length;     //用于记录顺序表的长度
10 }SqList;
11 
12 void swap(SqList *L,int i,int j)
13 {
14     int temp = L->r[i];
15     L->r[i] = L->r[j];
16     L->r[j] = temp;
17 }
18 
19 //首先初始化结构体的r数组
20 void main()
21 {
22     SqList n;
23     n.length = MAXSIZE;
24 
25     //srand((unsigned) time(NULL)); //用时间做种,每次产生随机数不一样
26 
27     int i = 0;
28     /*
29     for (; i<MAXSIZE ; i++) {
30         n.r[i] = rand() % 101;//产生0-100的随机数
31     }
32      */
33     n.r[0] = 4;
34     n.r[1] = 3;
35     n.r[2] = 2;
36     n.r[3] = 1;
37     
38     //依次输出
39     for (i=0;i<MAXSIZE;i++) {
40         printf("%d\n",n.r[i]);
41     }
42 }

  1.定义一个非标准冒泡排序算法的方法

 1 void BubbleSort0(SqList *L)
 2 {
 3     // 4,3,2,1
 4     //推导过程
 5     //第一次外层循环
 6     // 4和3比较 3,4,2,1
 7     // 3和2比较, 2,4,3,1
 8     // 3和1比较, 1,4,3,2
 9 
10     //第二次外层循环 从第2个元素开始
11     // 4和3比较  1,3,4,2
12     // 3和2比较  1,2,4,3
13 
14     //第三次外层循环,从第3个元素开始
15     // 4和3比较  1,2,3,4
16 
17     printf("非标准冒泡排序后结果:\n");
18 
19     int i,j;
20     for (i=0;i<L->length-1;i++){
21         for (j=i+1;j<L->length;j++){
22             if (L->r[i] > L->r[j])
23                 swap(L,i,j);
24         }
25     }
26 
27 }

  上面也说了,此方案并不能称得上'真正'的冒泡排序(具体可以看推到过程),因为不是相邻元素两两比较

 2. 冒泡排序算法 (待优化)

 1 void BubbleSort(SqList *L)
 2 {
 3     // 4,3,2,1 , 最多循环3次
 4 
 5     // 外层第一次循环
 6     //          j=0,  4和3比较, 3,4,2,1,
 7     //          j=1,  4和2比较, 3,2,4,1
 8     //          j=2,  4和1比较, 3,2,1,4
 9 
10     // 外层第二次循环 3,2,1,4
11     //          j=0,  3和2比较, 2,3,1,4,
12     //          j=1,  3和1比较, 2,1,3,4
13     //          j=2,  3和4比较, 2,1,3,4
14 
15     // 外层第三次循环 2,1,3,4
16     //          j=0,  2和1比较, 1,2,3,4,
17     //          j=1,  2和3比较, 1,2,3,4,
18     //          j=2,  3和4比较, 1,2,3,4,
19 
20     // 由此可推出, 内层只需要 n - 1次循环, 外层只需要循环 n-1次即可
21     //从第三次外层循环可以看出,其实内循环是没有比较再去比较2和3, 3和4的
22 
23     printf("冒泡排序后结果:\n");
24     int i,j;
25     for (i=1;i<L->length;i++){
26         for (j=0;j<L->length-1;j++){
27             if (L->r[j] > L->r[j+1])
28                 swap(L,j,j+1);
29         }
30     }
31 }

  优化后的版本:

 1 //冒泡排序,优化版
 2 void BubbleSort1(SqList *L)
 3 {
 4     // 4,3,2,1 , 最多循环3次
 5 
 6     // 外层第一次循环
 7     //          m = 3
 8     //          j=0,  4和3比较, 3,4,2,1,
 9     //          j=1,  4和2比较, 3,2,4,1
10     //          j=2,  4和1比较, 3,2,1,4
11 
12     // 外层第二次循环 3,2,1,4
13     //          m = 2 , 因为最大的已经沉入最底
14     //          j=0,  3和2比较, 2,3,1,4,
15     //          j=1,  3和1比较, 2,1,3,4
16 
17     // 外层第三次循环 2,1,3,4
18     //          m = 1, 前面循环的2次, 最后2个元素已经排好序, 只需要循环1次,比对前2个即可
19     //          j=0,  2和1比较, 1,2,3,4,
20 
21 
22     printf("冒泡排序(优化算法)结果:\n");
23     int i,j,m = L->length; //m = 4
24     for (i=1;i<L->length;i++){
25 
26         m -= 1;
27 
28         for (j=0;j<m;j++){
29             if (L->r[j] > L->r[j+1])
30                 swap(L,j,j+1);
31         }
32     }
33 }

  结合上面 理解冒泡排序的实现过程. 调用BubbleSort1 打印 

1    BubbleSort1(&n);
2 
3     for (i=0;i<MAXSIZE;i++) {
4         printf("%d\n",n.r[i]);
5     }

 

  

posted on 2016-11-10 15:48  睡着的糖葫芦  阅读(2108)  评论(0编辑  收藏  举报