冒泡排序应该是最常用的排序方法,我接触的第一个排序算法就是冒泡,老师也经常那这个做例子。
冒泡排序是一种交换排序,
基本思想:
通过两两比较相邻的记录,若反序则交换,知道没有反序的记录为止。
例子:
依次类推。这里可以看出,每次比较从最后一个开始,向前比较,若反序则交换;
每次都保证了是两两相邻的记录比较。
冒泡排序的代码:
1 void bubble_sort (myDataType *ary,int len) 2 { 3 int i,j; 4 for (i=0;i<len;i++) 5 { 6 for (j=len-2;j>=i;j--) 7 { 8 if (ary[j] > ary[j+1]) 9 { 10 myDataType temp = ary[j]; 11 ary[j] = ary[j+1]; 12 ary[j+1] = temp; 13 } 14 } 15 } 16 17 }
完整代码:
1 // sort-bubble.cpp : 定义控制台应用程序的入口点。 2 // 3 - 4 #include "stdafx.h" 5 6 7 typedef int myDataType; 8 myDataType src_ary[10] = {9,1,5,8,3,7,6,0,2,4}; 9 10 void prt_ary(myDataType *ary,int len) 11 { 12 int i=0; 13 while(i < len) 14 { 15 printf(" %d ",ary[i++]); 16 } 17 printf("\n"); 18 } 19 20 void bubble_sort (myDataType *ary,int len) 21 { 22 int i,j; 23 for (i=0;i<len;i++) 24 { 25 for (j=len-2;j>=i;j--) 26 { 27 if (ary[j] > ary[j+1]) 28 { 29 myDataType temp = ary[j]; 30 ary[j] = ary[j+1]; 31 ary[j+1] = temp; 32 } 33 } 34 } 35 36 } 37 38 39 int _tmain(int argc, _TCHAR* argv[]) 40 { 41 printf("before sort:\n"); 42 prt_ary(src_ary,10); 43 44 bubble_sort(src_ary,10); 45 46 printf("after sort:\n"); 47 prt_ary(src_ary,10); 48 49 50 51 getchar(); 52 return 0; 53 }
结果:
附录:
另外冒泡排序还有其他变形,
比如:
可以设置一个哨兵下标,对该下标元素和之后的每一个元素做比较,选取最小的元素交换,这样一次类推,每次都是一个最小的元素。
如图:
代码:
1 void bubble_sort_modify1(myDataType *ary,int len) 2 { 3 int i,j; 4 for (i=0;i<len;i++) // 哨兵下标 5 { 6 for (j=i+1;j<len;j++) //欲比较的下标 7 { 8 if (ary[i] > ary[j]) 9 { 10 myDataType temp; 11 temp = ary[i]; 12 ary[i] = ary[j]; 13 ary[j] = temp; 14 } 15 } 16 } 17 }
这个不是我们标准的冒泡排序算法,但是却很好理解,用的也多。
该算法还可以改进,每次交换顺序耗费时间,可以在比较过程中,将最小值的小标记下,循环结束后,交换。这样每次循环交换操作只有一次。
对标准冒泡排序还可以优化:
10个数字需要循环10趟,如果在第3趟就将所有的顺序排序好了,这样后面的7趟还是要继续执行,但是不起作用。所以可以在比较中添加一个标记
用来查看一次循环是否做了调整,如果没有,则说明排序好了,不用在执行剩余的循环了。
1 void bubble_sort_opt (myDataType *ary,int len) 2 { 3 int i,j; 4 bool flag = true; //增加一个标记元素 5 for (i=0;i<len && flag;i++) //判断之前循环是否执行了交换操作 6 { 7 flag = false; 8 for (j=len-2;j>=i;j--) 9 { 10 if (ary[j] > ary[j+1]) 11 { 12 myDataType temp = ary[j]; 13 ary[j] = ary[j+1]; 14 ary[j+1] = temp; 15 flag = true; //查看该循环是否执行了操作 16 } 17 } 18 } 19 20 }