在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 }