话说,从acm开始,除了刚刚开始的时候写过几次冒泡和选择排序,之后便被TLE弄乖了,转投sort怀抱。

  不过,很多时候,不再去追求那种极速的时候,去改进一个算法也是很有趣的事情。

  你会说,理解这些有意义么?能比得过快排么?

  我想说,我们所追逐的就是一种过程,是对这种思路的更进一步的理解,也许,会有意外发现。

  

  话不多说,先放上最朴素的冒泡(以下排序的结果一律从小到大):

  1.从第一个元素开始,与之后相邻的比较,若反序,则交换,这样,一次循环之后,最后一个数一定是最大的,就像泡泡一样,大的慢慢升上来了。

  2.重复上述操作,直到n-1次操作之后,整个序就排好了。
  

//冒泡排序1
void Bubble_1(int a[], int n)
{
       int i, j;
       for (i = 0; i < n; i++)
              for (j = 1; j < n - i; j++)//这里稍微优化一点,书上写的实在不能看
                     if (a[j - 1] > a[j])
                            Swap(a[j - 1], a[j]);
}

 

  优化一:非常常见的优化,加上一个flag,当有一趟没有交换的时候,表示已经有序了——课本也就到此为止了,但真的就到这为止了么?

  优化二:对步骤一,从前往后一趟,第二趟从后往前循环,之后再从前往后一趟,如此往复循环,这样可以极大的提高冒泡的稳定性,比如(2,3,4,5,……,n,1)。

  优化三:假设,有100个数,后面80个数全部有序并且最小的一个大于前面20个数中的任意一个,我们可以进一步的优化flag的意义,这里flag为最后一次交换的       位置,这样,针对上面的情况或者中途变化成类似的情况,执行次数大大减少。很开心的是,这三个优化中,第三个是第一个的升级,而第二个可以和第       三个结合在一起,形成更有效的方法

  优化四:这样想一下,如果以一个点为标准,比他大的放右边,比他小的放左边,这样就能同时冒多个泡泡(比这个大的一次性全部冒到他的右边,小的也一次性

      冒到左边)。再对左边和右边进行分治,重复操作,就能非常快的得到一个有序列了——咦,是不是很熟悉,对了,这就是快排!!!

  

  这就是乐趣,万变不离其宗,现在你还小看冒泡么?

 

posted on 2012-07-21 00:38  FreeAquar  阅读(279)  评论(0编辑  收藏  举报