目录
1 理论
1.1 何为冒泡?
顾名思义,排序的方式如同水里的泡泡一样,一个接着一个往上冒出。如果进行升序排序,则把第一小的元素比较交换至第一的位置、第二小的交换至第二的位置,以此类推直到全部元素排序好。
1.2 动画演示
2 实践
2.1 JAVA实现
/**
* 升序冒泡(从后往前升序)
* @author liquid
* @date 2022年10月21日
* @param data 待排数据
* @return 升序排序的结果
*/
public static int[] bubbleSort01(int[] data) {
int[] result = data.clone();
int sortedCount = 0;
// 每次循环至少排好1个
while (++sortedCount < result.length) {
for (int i = result.length - 1; i > 0; i--) {
if(result[i] < result[i - 1]) {
int temp = result[i];
result[i] = result[i - 1];
result[i - 1] = temp;
}
}
}
return result;
}
/**
* 降序冒泡(从后往前降序)
* @author liquid
* @date 2022年10月21日
* @param data 待排数据
* @return 降序排序的结果
*/
public static int[] bubbleSort02(int[] data) {
int[] result = data.clone();
int sortedCount = 0;
// 每次循环至少排好1个
while (++sortedCount < result.length) {
for (int i = result.length - 1; i > 0; i--) {
if(result[i] > result[i - 1]) {
int temp = result[i];
result[i] = result[i - 1];
result[i - 1] = temp;
}
}
}
return result;
}
/**
* 降序冒泡(从前往后升序)
* @author liquid
* @date 2022年10月24日
* @param data 待排数据
* @return 升序排序的结果
*/
public static int[] bubbleSort03(int[] data) {
int[] result = data.clone();
int sortedCount = 0;
// 每次循环至少排好1个
while (++sortedCount < result.length) {
for (int i = 1; i < result.length; i++) {
if(result[i - 1] > result[i]) {
int temp = result[i];
result[i] = result[i - 1];
result[i - 1] = temp;
}
}
}
return result;
}
/**
* 降序冒泡(从前往后降序)
* @author liquid
* @date 2022年10月24日
* @param data 待排数据
* @return 降序排序的结果
*/
public static int[] bubbleSort04(int[] data) {
int[] result = data.clone();
int sortedCount = 0;
// 每次循环至少排好1个
while (++sortedCount < result.length) {
for (int i = 1; i < result.length; i++) {
if(result[i - 1] < result[i]) {
int temp = result[i];
result[i] = result[i - 1];
result[i - 1] = temp;
}
}
}
return result;
}
2.3 C++实现(待补充)
待补充~
2.2 JavaScript实现(待补充)
待补充~
2.4 Python实现(待补充)
待补充~
3 性能分析
3.1 时间复杂度
相关数学知识:
等差数列求和公式: s n = n ( a 1 + a n ) 2 等差数列求和公式 : s_n = \frac{n(a_1+a_n)}{2} 等差数列求和公式:sn=2n(a1+an)
最糟糕的情况下,是类似于这样一个待排数列:9、8、7、6、5、4、3、2、1
若需对其进行升序排序,则需要循环9次,每次比较的次数均比上一次少一次
即时间复杂度为:(n - 1) + (n - 2) + (n - 3) + … + 3 + 2 + 1 = ( n − 1 ) ( n − 1 + 1 ) 2 = 1 2 n 2 − 1 2 n = O ( n 2 ) \frac{(n-1)(n-1+1)}{2}=\frac{1}{2}n^2-\frac{1}{2}n=O(n^2) 2(n−1)(n−1+1)=21n2−21n=O(n2)
3.2 空间复杂度
冒泡排序过程中仅用到一个临时变量,不会因待排数列个数的增加而增加,
故空间复杂度为: O ( 1 ) O(1) O(1)
3.3 稳定性
待补充~
4 双向冒泡排序(鸡尾酒排序)
4.1 原理
待补充~
4.2 JAVA实现
/**
* 双向冒泡升序 - 鸡尾酒排序
* @author liquid
* @date 2022年10月24日
* @param data 待排数据
* @return 排序结果(升序)
*/
public static int[] bubbleSortTowWay01(int[] data) {
int[] result = data.clone();
int sortedCount = 0;
int i = 1;
int j = data.length - 2;
// true为由前至后,false为由后至前
boolean front = true;
while (++sortedCount < result.length) {
if (front) {
// 从前往后(将大的推到后面)
for (int k = i; k <= j; k++) {
if (result[k] > result[k + 1]) {
int temp = result[k];
result[k] = result[k + 1];
result[k + 1] = temp;
}
}
j--;
front = false;
continue;
}
// 从后往前(将小的推到前面)
for (int k = j; k >= i; k--) {
if (result[k] < result[k -1]) {
int temp = result[k];
result[k] = result[k - 1];
result[k - 1] = temp;
}
}
i++;
front = true;
}
return result;
}
/**
* 双向冒泡降序 - 鸡尾酒排序
* @author liquid
* @date 2022年10月24日
* @param data 待排数据
* @return 排序结果(降序)
*/
public static int[] bubbleSortTowWay02(int[] data) {
int[] result = data.clone();
int sortedCount = 0;
int i = 1;
int j = data.length - 2;
// true为由前至后,false为由后至前
boolean front = true;
while (++sortedCount < result.length) {
if (front) {
// 从前往后(将大的推到后面)
for (int k = i; k <= j; k++) {
if (result[k] < result[k + 1]) {
int temp = result[k];
result[k] = result[k + 1];
result[k + 1] = temp;
}
}
j--;
front = false;
continue;
}
// 从后往前(将小的推到前面)
for (int k = j; k >= i; k--) {
if (result[k] > result[k -1]) {
int temp = result[k];
result[k] = result[k - 1];
result[k - 1] = temp;
}
}
i++;
front = true;
}
return result;
}
4.3性能分析
4.3.1 时间复杂度
与冒泡一致,均为 O ( n 2 ) O(n^2) O(n2)
4.3.2 空间复杂度
与冒泡一致,均为 O ( 1 ) O(1) O(1)
4.3.3 稳定性
稳定