思想:
可以看做交换排序的一种。交换排序的思想是:两两比较待排序记录的关键字,发现两个记录的次序相反时就进行交换,直到没有反序的记录为止。(反序:设有两个下标i和j,满足i<j且A[i]>A[j],那么A[i]和A[j]就是一个反序对)
冒泡算法的思想是:把待排序的元素看做是竖着排列的“气泡”,较小的元素比较轻,从而要上浮。在冒泡排序中对序列扫描若干遍。在一次扫描过程中,依次比较相邻的两个元素,如果A[j]>A[j+1](即:轻的气泡在下边,重的气泡在上边),就交换它们。在这一系列操作期间,重气泡向下移动,直到移动到Rn为止。重复该过程,得到Rn-1,Rn-2,…位置上的记录,使得所有记录有序。
伪代码:
下面这个伪代码应该是大家都很清楚的。
Bubble-Sort(A)
For i从1到n-1
For j从1到n-i
If(A[j] > A[j+1])
交换A[j]和A[j+1]
算法分析:
冒泡排序的时间复杂度是O(n^2)
冒泡排序是一种稳定的排序,也是就地排序
改进:
1、 记录最后一次交换发生的位置
在每一扫描过程中,右边的所有记录,包括最后被交换的那个记录在内,都必然会处于它们的最后位置上,所以在随后的扫描中无需考虑它们(《计算机程序设计艺术》第3卷5.2节)。这句话的意思是:在每一次扫描中,至少有一个元素将被放在它的最后位置上,但是也可能有多个元素都被放在最重位置上。和这句话相关的伪代码如下:其中,遍历t用来记录每次扫描中最后一次交换发生的位置
Bubble-Sort(A)
Bound=lenth[A]
While true
T=0
J=1
Whiel j<bound-1
If(R[j]>R[j+1])
交换R[j]和R[j+1]
T=j
If(t==0)
break
2、鸡尾混合排序——改变扫描方向的冒泡排序
它以相反的方向交替地进行扫描。略微减少了进行比较的平均次数。具体的例子看下面:(粗体为本次扫描后有序的元素)
503 087 512 061 908 170 897 275 653 426 154 509 612 677 765 703
从左向右扫描,得到最大元素908
087 503 061 512 170 897 275 653 426 154 509 612 677 765 703 908
从左向右扫描,得到最小元素061
061 087 503 154 512 170 897 275 653 426 509 612 677 703 765 908
从左向右扫描,得到最大元素897
061 087 154 503 170 512 275 653 426 509 612 677 703 765 897 908
从右向左扫描,得到最小元素503
061 087 154 170 503 275 512 426 653 509 612 677 703 765 897 908
从左向右扫描,得到最大元素653
061 087 154 170 503 275 426 512 509 612 653 677 703 765 897 908
061 087 154 170 503 275 426 509 512 612 653 677 703 765 897 908
实用性:
但是要注意:在冒泡排序算法的所有改进中,都没有一个能到处比直接插入更好的算法。因此,冒泡排序除了迷人的名字和导致了某些有趣的理论问题之外,似乎没什么值得推荐的。(《计算机程序设计艺术》第 3 卷 5.2 节 104 页)