排序算法 冒泡排序

来源:互联网 发布:行知实验小学 编辑:程序博客网 时间:2024/04/30 09:09

       前几天想写个快速排序,不写不知道,一写吓一跳,各种问题错误如雨后春笋般,深感自己编码能力之差劲,于是想把各种排序算法都来简单实现一下,随便把自己犯的错记录下来,希冀以后别再出那种错了,真是想起来都不好意思。

       冒泡算法(Bubble Sort) 介绍点进去看就可啦,代码使用C++实现的,其实只是这种代码的话,C,C++,JAVA都是一样的。

void bubbleSort(int array[] ,int n){int temp = 0;for(int i = 0; i < n; i++){for(int j = 0; j < n - i -1; j++){if(array[j] > array[j+1]){swap(array[j], array[j+1]);}}}}
       
       图片源wikipeidia
       这里需要注意一点的是第4行的for循环中止条件,在冒泡排序中,后面元素是排好序的,前面的元素才是乱序的。而(n - i - 1)是因为外部传入的n为数组的长度,而下方的其实会用到array[j+1],若不-1则会数组越界。在循环的边界判断上是否+-1是否应加上=,这些都是需要严格注意的地方。而且在这种地方切忌使用散弹枪法,不想对不对,直接弄个数组测试,这样其实是非常危险的,过小或非严格条件的测试样本并不能保证你算法的正确。
       这里再说一下冒泡排序的时间复杂度.简单的来看,两层for循环,复杂度即O(n^2).我们也可以从数学上进行分析,假设有n位数进行排序,则有总的比较次数为 n+(n-1)+(n-2)...+1=n*(n-1)/2=(n^2)/2+1/2 按O()的规则(简单来说就是取大头,看重的是增长率)即是O(n^2).
       wiki上也提到有一种改进的冒泡排序法,往返排序也称为鸡尾酒排序,涟漪排序等等(这货名字真多),它改进在于冒泡排序每次只向尾部沉下最大的,而它则一次向尾部沉下最大,一次向头部浮出最小的。其C++代码为:
void cocktailSort(int array[], int n){bool isSwap=true;int bottom = 0;int top = n-1;while(isSwap == true){isSwap = false;for(int i = bottom; i< top; i++){if(array[i] > array[i+1]){swap(array[i], array[i+1]);isSwap = true;}}top--;for(int i = top; i > bottom; i--){if(array[i] < array[i-1]){swap(array[i], array[i-1]);isSwap = true;}}bottom++;}}
       图片源 wikipeidia
       这里要注意的是如果把第5行的判断条件由wihle(isSwap==true)变为while(bottom<=top)稍加思考便会发现,这样会使判断次数增多。其实在冒泡排序中也可以加入这样一个变量来提高对已排好序的数据情况下的速度,但是这种小修改并不能对算法的整体速度得到本质上提高。