前言:
上一篇说的是“插入排序”,这篇讲讲“冒泡”,算法比较简单篇幅会比较短;既然要做一个系列再短也要讲啊~!
概念(百度上抄的):
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
-
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
-
针对所有的元素重复以上的步骤,除了最后一个。
-
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
举个栗子:
在一个数组中升序排列,也就是最小的在最左、最大的在最右。
3 | 1 | 7 | 4 | 2 | 8 | 5 |
1、指针在数组【0】的位置:3 与 数组【1】的位置:1比较,不符合,交换 1->3;
1 | 3 | 7 | 4 | 2 | 8 | 5 |
2、指针在数组【1】的位置:3 与 数组【2】的位置:7比较,符合,不交换;
1 | 3 | 7 | 4 | 2 | 8 | 5 |
3、指针在数组【2】的位置:7 与 数组【3】的位置:4比较,不符合,交换 4->7;
1 | 3 | 4 | 7 | 2 | 8 | 5 |
... ...最后,
1 | 3 | 4 | 2 | 7 | 5 | 8 |
以上为一次“冒泡”过程,冒泡排序是由多次冒泡构成。
由此可见每次冒泡操作会确定当前集合中一个元素的位置。那么 N 个元素的集合需要多少次比较?
(n-1)+(n-2)+(n-3)+...+1 = n(n-1)/2 ,由此可见冒泡排序的时间复杂度 O(n^2)。冒泡排序是一种“稳定排序”算法(相同的元素
不会交换位置)。
补一个Java代码:
/**
* 冒泡排序
* @param array 目标数组
* @param flag 降序-0 升序-1
* @return 源数组
*/
public static int[] bubbleSort(int[] array, boolean flag) {
if (array.length < 2)
return array;
for (int j = array.length - 1; j > 0; j--) {
for (int i = 0; i < j; i++) {
if (array[i] < array[i + 1]^flag) {
int tmp = array[i + 1];
array[i + 1] = array[i];
array[i] = tmp;
}
}
}
return array;
}
补一个“鸡尾酒排序”:
分别从两端冒泡,弥补了单向冒泡的缺点,一定程度上减少元素移动,贴个代码就不解释了。
public static int[] cocktailSort(int[] array) {
for (int i = 0; i < array.length / 2; i++) {
int count = array.length - 1 - i;
for (int j = i; j < count; j++) {
if (array[j] < array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
for (int j = count - 1; j > i; j--) {
if (array[j] > array[j - 1]) {
int temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
}
}
return array;
}