介绍
冒泡排序就像水里的泡泡,较小的数向上浮,较大的数向下沉。冒泡排序的每一趟循环完成之后,会在数组的一端得到本次循环最大或最小的数,过程比较像冒泡泡,故叫做冒泡排序。
分析
- 这里以升序为例,冒泡排序一轮都会将两个相邻的数进行比较,若第一个数比第二个数大,则交换二者的位置。反之则继续向下比较,直到第一次循环结束。
- 第二次循环与第一次相同,从第一个元素开始与其相邻的元素进行比较。
- 以此类推直至循环结束。
例子
下面我们来看一个例子。
4 | 13 | 0 | 15 | 11 | 13 | 3 | 14 | 15 | 14 |
---|
第一轮循环
第一次比较 4 和13,4小于13不进行操作,继续向下比较
第一次比较后的数组
4 | 13 | 0 | 15 | 11 | 13 | 3 | 14 | 15 | 14 |
---|
第二次比较13 和0, 13大于0,交换13和0的位置,继续向下比较。
第二次比较后的数组
4 | 0 | 13 | 15 | 11 | 13 | 3 | 14 | 15 | 14 |
---|
第三次比较 13 和15,13小于15不进行操作,继续向下比较。
第三次比较后的数组
4 | 0 | 13 | 15 | 11 | 13 | 3 | 14 | 15 | 14 |
---|
第四次比较 15和11,15大于13交换,继续向下比较
第四次比较后的数组
4 | 0 | 13 | 11 | 15 | 13 | 3 | 14 | 15 | 14 |
---|
第五次比较 15 和13,15大于13交换,继续向下比较
第五次比较后的数组
4 | 0 | 13 | 11 | 13 | 15 | 3 | 14 | 15 | 14 |
---|
第六次比较 15 和3,15大于3交换,继续向下比较
第六次比较后的数组
4 | 0 | 13 | 11 | 13 | 3 | 15 | 14 | 15 | 14 |
---|
第七次比较 15 和14,15大于14交换,继续向下比较
第七次比较后的数组
4 | 0 | 13 | 11 | 13 | 3 | 14 | 15 | 15 | 14 |
---|
第八次比较 15 和15,15不大于15不进行操作,继续向下比较
第八次比较后的数组
4 | 0 | 13 | 11 | 13 | 3 | 14 | 15 | 15 | 14 |
---|
第九次比较 15 和14,15大于14交换,第一轮循环结束
第九次比较后的数组
4 | 0 | 13 | 11 | 13 | 3 | 14 | 15 | 14 | 15 |
---|
第一轮循环结束,得到了数组中的最大值15,在数组的最后一位。
下面进行第二轮循环
0 | 4 | 11 | 13 | 3 | 13 | 14 | 14 | 15 | 15 |
---|
第三轮循环
0 | 4 | 11 | 3 | 13 | 13 | 14 | 14 | 15 | 15 |
---|
第四轮循环
0 | 4 | 3 | 11 | 13 | 13 | 14 | 14 | 15 | 15 |
---|
从这里开始数组就已经有序了,但程序不会停止,直到每一轮都执行完才结束。优化的算法会在最下面给出。
第五轮循环
0 | 4 | 3 | 11 | 13 | 13 | 14 | 14 | 15 | 15 |
---|
第六轮循环
0 | 4 | 3 | 11 | 13 | 13 | 14 | 14 | 15 | 15 |
---|
第七轮循环
0 | 4 | 3 | 11 | 13 | 13 | 14 | 14 | 15 | 15 |
---|
第八轮循环
0 | 4 | 3 | 11 | 13 | 13 | 14 | 14 | 15 | 15 |
---|
第九轮循环
0 | 4 | 3 | 11 | 13 | 13 | 14 | 14 | 15 | 15 |
---|
循环结束,数组中的数已经按照升序排序了。
源代码
// 排序算法
public static void main(String[] args) {
int[] array = {4, 13, 0, 15, 11, 13, 3, 14, 15, 14};
// 输出
System.out.print("排序前的数组:");
for (int k : array) {
System.out.print(k + " ");
}
// 自定义排序方法
sort1(array);
// 输出
System.out.print("\n排序后的数组:");
for (int k : array) {
System.out.print(k + " ");
}
}
// 冒泡排序
static void sort1(int[] array) {
// 排序
// 共进行array.length - 1轮循环
for (int i = 0; i < array.length - 1; i++) {
// 这里因为每一轮排序之后都会将每一轮中最大的一个数放到数组后面,所以从第一轮开始,往后每一轮都会减少一次比较次数
for (int j = 0; j < array.length - i - 1; j++) {
// 交换
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
System.out.println("\n第" + (i + 1) + "轮排序:" + Arrays.toString(array));
}
}
优化
这里定义了一个flag标志,用于判断内层循环中是否进行位置交换。若不进行位置交换,则表明数组中的数已经是有序的,不需要再继续执行了。反之,继续执行。
// 冒泡排序
static void sort1(int[] array) {
boolean flag;
// 排序
for (int i = 0; i < array.length - 1; i++) {
flag = true;
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
flag = false;
}
}
if (flag) {
break;
}
System.out.println("\n第" + (i + 1) + "轮排序:" + Arrays.toString(array));
}
}