介绍
冒泡排序是比较排序的一种,核心思想:相邻元素进行比较,大的在后,小的在前;其特点:
- N个元素,需要进行i=N-1排序
- 第i次排序,需要进行N-i次交换。每次排序可以确定一个元素位置(最大方向顺序位置,或者最小方向顺序位置)
- 根据数组正序或者逆序扫描,有两种实现。
- .时间复杂度: O(N^2)
- 空间复杂度: O(1)
- 稳定性:稳定
倒序扫描
* 倒序扫描:
* 1. 比较下标从SIZE -1 开始,相邻的比较,大的在后,小的在前
* 2. 一次排序得到一个“最小值”方向的顺序位置
* 3. 将“最小值”位置从扫描范围排除
* 4. 循环1-3步,直到扫描范围只剩下比较下标。
示例
47 764 811 812 712 885 683 623 745 130
第1次交换 47 130 764 811 812 712 885 683 623 745
第2次交换 47 130 623 764 811 812 712 885 683 745
第3次交换 47 130 623 683 764 811 812 712 885 745
第4次交换 47 130 623 683 712 764 811 812 745 885
第5次交换 47 130 623 683 712 745 764 811 812 885
第6次交换 47 130 623 683 712 745 764 811 812 885
第7次交换 47 130 623 683 712 745 764 811 812 885
第8次交换 47 130 623 683 712 745 764 811 812 885
第9次交换 47 130 623 683 712 745 764 811 812 885
核心代码
for (int index = 1; index < SIZE; index ++) {
for (int jndex = SIZE -1; jndex > index - 1; jndex --) {
if (array[jndex] < array[jndex - 1]) {
temp = array[jndex];
array[jndex] = array[jndex-1];
array[jndex-1] = temp;
}
}
}
正序扫描
* 正序扫描:
* 1. 比较下标从0开始,相邻的比较,大的在后,小的在前
* 2. 一次排序得到一个“最大值”方向的顺序位置
* 3. 将“最大值”位置从扫描范围排除
* 4. 循环1-3;直到比较下标 + 1 = SIZE -1结束
示例
47 764 811 812 712 885 683 623 745 130
第1次交换 47 764 811 712 812 683 623 745 130 885
第2次交换 47 764 712 811 683 623 745 130 812 885
第3次交换 47 712 764 683 623 745 130 811 812 885
第4次交换 47 712 683 623 745 130 764 811 812 885
第5次交换 47 683 623 712 130 745 764 811 812 885
第6次交换 47 623 683 130 712 745 764 811 812 885
第7次交换 47 623 130 683 712 745 764 811 812 885
第8次交换 47 130 623 683 712 745 764 811 812 885
第9次交换 47 130 623 683 712 745 764 811 812 885
核心代码
for (int index = 1; index < SIZE; index ++) {
// 3. 相邻元素进行交换, 第i次排序,需要交换N-index次
for (int jndex = 0; jndex < SIZE - index; jndex ++) {
if (array[jndex] > array[jndex+1]) {
temp = array[jndex];
array[jndex] = array[jndex+1];
array[jndex+1] = temp;
}
}
}```
## 完整代码示例
```java
package algorithms;
import java.util.Random;
/**
* 冒泡排序:相邻元素进行交换。
* 1. N个元素,需要进行N-1排序
* 2. 第i次排序,需要进行N-i次交换。
*
* 总结:
* 时间复杂度: O(N^2)
空间复杂度: O(1)
稳定性:稳定
*
* @author jiazhiqiang
*
*/
public class BubbleSort {
public static final int SIZE = 10;
public static void main(String args[]) {
int[] array = new int [SIZE];
int[] array2 = new int [SIZE];
Random random = new Random();
//1. 初始化赋值
for (int index = 0; index < SIZE; index ++) {
array[index] = random.nextInt(999);
array2[index] = array[index];
}
bubbleSortAsc(array);
System.out.println("");
bubbleSortDesc(array2);
}
/**
* 倒序扫描:
* 1. 比较下标从SIZE -1 开始,相邻的比较,大的在后,小的在前
* 2. 一次排序得到一个“最小值”方向的顺序位置
* 3. 将“最小值”位置从扫描范围排除
* 4. 循环1-3步,直到扫描范围只剩下比较下标。
* @param array
*/
public static void bubbleSortDesc(int[] array) {
// 原始输出显示
for (int index = 0; index < SIZE; index ++) {
System.out.printf("\t %d", array[index]);
}
System.out.println("");
int temp = 0;
//2. N 个元素,需要N-1次排序
for (int index = 1; index < SIZE; index ++) {
for (int jndex = SIZE -1; jndex > index - 1; jndex --) {
if (array[jndex] < array[jndex - 1]) {
temp = array[jndex];
array[jndex] = array[jndex-1];
array[jndex-1] = temp;
}
}
rankPrint(index, array);
}
}
private static void rankPrint(int time, int[] array) {
// 打印第i次排序后的结果
System.out.printf("第%d次交换", time);
for (int kndex = 0; kndex < SIZE; kndex ++) {
if (kndex != 0) {
System.out.printf("\t %d",array[kndex]);
} else {
System.out.printf(" %d",array[kndex]);
}
}
System.out.println("");
}
/**
* 正序扫描:
* 1. 比较下标从0开始,相邻的比较,大的在后,小的在前
* 2. 一次排序得到一个“最大值”方向的顺序位置
* 3. 将“最大值”位置从扫描范围排除
* 4. 循环1-3;直到比较下标 + 1 = SIZE -1结束
*
*
* @param array
*/
public static void bubbleSortAsc(int[] array) {
// 原始输出显示
for (int index = 0; index < SIZE; index ++) {
System.out.printf("\t %d", array[index]);
}
System.out.println("");
int temp = 0;
//2. N 个元素,需要N-1次排序
for (int index = 1; index < SIZE; index ++) {
// 3. 相邻元素进行交换, 第i次排序,需要交换N-index次
for (int jndex = 0; jndex < SIZE - index; jndex ++) {
if (array[jndex] > array[jndex+1]) {
temp = array[jndex];
array[jndex] = array[jndex+1];
array[jndex+1] = temp;
}
}
rankPrint(index, array);
}
}
}