冒泡排序(bubble sort)
冒泡排序
冒泡排序(bubble sort) 是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
算法描述
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤1~3,直到排序完成。
算法分析
时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 |
---|---|---|---|---|
\(O(n^2)\) | \(O(n^2)\) | \(O(n)\) | \(O(1)\) | 稳定 |
例子
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220221180241381-1490202042.jpg)
按照冒泡排序的思想 把相邻的元素两两比较,当一个元素大于右侧相邻元素时,交换它们的位置;当一个元素小于或等于右侧相邻元素时,位置不变 。
![](https://img2022.cnblogs.com/blog/2758160/202202/2758160-20220221180559856-1077147643.jpg)
完成一轮后得到
进行第二轮时,不需要处理最后一位
完成第二轮后得到
接下来 (紫色是已经有序的元素)
动图演示
![](https://images.cnblogs.com/cnblogs_com/blogs/734424/galleries/2112342/o_220221105357_%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F.gif)
代码
Java
public static void bubbleSort(E[] array){
for(int i = 0; i < array.length - 1; i++){
for(int j = 0; j < array.length - i - 1; j++){
E tmp = 0;
if(array[j].compareTo(array[j+1]) > 0)
exch(array, j, j+1);
}
}
}
python
def bubbleSort(arr):
for i in range(1, len(arr)):
for j in range(0, len(arr)-i):
if arr[j] > arr[j+1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
算法优化
冒泡排序的问题:
- 当一轮下来没有交换的元素,说明整个数列已经有序,没有必要进行之后的循环(标记有序
boolean isSorted;
) - 有序集合只一轮增加一个,若整个数列偏向于有序则,即右侧部分已经有序,则会重复很多无用的比较(标记无序边界
int sortBorder
)
public static void sort(int array[]){
int tmp = 0;
//记录最后一次交换的位置
int lastExchangeIndex = 0;
//无序数列的边界,每次比较只需要比到这里为止
int sortBorder = array.length - 1;
for(int i = 0; i < array.length; i++){
//有序标记,每一轮的初始是true
boolean isSorted = true;
for(int j = 0; j < sortBorder; j++){
if(array[j] > array[j+1]){
tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
//把无序数列的边界更新为最后一次交换元素的位置
lastExchangeIndex = j;
}
}
sortBorder = lastExchangeIndex;
if(isSorted){
break;
}
}
}