上一篇讲了桶排序。虽说桶排序的时间效率较高但是存在的缺陷也很明显。比如当数字非常大的时候,需要消耗大量的空间,甚至数组根本开不到所给定的数字的上限。针对这种情况,可以采取其他的排序算法。本文介绍一种新的排序算法----------冒泡排序
一、冒泡排序算法的思想很简单:就是两两比较,如有需要则交换,然后遍历所有的元素即可。
不玩抽象,直接上栗子:
输入五个数字 12 35 99 18 76 按照从大到小的顺序输出,具体的算法如下:
第一次循环:
比较12 与 35 ,12<35 交换顺序 ,此时数组中数字位置为{35,12,99,18,76}
比较12 与 99 ,12<99 交换顺序 ,此时数组中数字的位置为{35,99,12,18,76}
比较12与18, 12<18 交换顺序,此时数组中数字的位置为{35,99,18,12,76}
比较12与76, 12<76交换顺序,此时数组中数字的位置为{35,99,18,76,12}
此时12由最初的位置移动到最尾端,第一个数字的顺序由此确定了。
第二次循环:
与第一次循环类似,以下简写了
比较35与99--------{99,35,18,76,12}
比较35与18--------{99,35,18,76,12}
比较18与76--------{99,35,76,18,12}
由于12已经确定,故不需要额外比较,此时18的位置确定
第三次循环:
比较99与35--------{99,35,76,18,12}
比较35与76--------{99,76,35,18,12}
35 的位置确定
第四次循环:
比较99与76-----{99,76,35,18,12}
76的位置确定
第五次循环:
99与76比较-------{99,76,35,18,12}
排序完毕
具体代码如下:
#include<stdio.h> #define N 100 int main() { int n,a[N]; int i,j,len,temp; while(scanf("%d",&n)!=EOF) { for(i=0;i<n;++i) scanf("%d",&a[i]); // bubble sort (From big to small) len = n; while(--len) { for(j=0;j<len;++j) { if(a[j]<a[j+1]) { temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } } for(i=0;i<n;++i) printf("%3d ",a[i]); printf(" "); } return 0; }
二、算法分析
从上面不难发现,冒泡排序的时间复杂度最好的情况为比较n次即O(n),最坏的情况下需要进行n*(n-1)/2次比较即o(n^2) ,故冒泡排序的时间复杂度为o(n^2)
在来分析时间复杂度:从程序不难发现整个运行过程总,只需要借助一个临时变量temp即可,故空间复杂度为o(1)
有没有更好的排序算法呢? 答案是肯定的啦,具体详见下一篇