从冒泡排序开始
Posted javasanity
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从冒泡排序开始相关的知识,希望对你有一定的参考价值。
欢迎点击蓝色字关注“javasanity”
冒泡排序(bubble sort)在排序算法中应该算是比较经典也比较简单的一个了,咱们就直入正题吧。
①
冒泡排序思想
其实它的名称都已经够直白了对吧,就是“冒泡”嘛。但是具体是怎么“冒”的呢?就是从数组中第一个位置开始,相邻元素两两比较大小,如果左边的元素大于右边的元素,则交换两元素的位置,否则,就保持它们在数组中的位置不变;然后再继续比较接下来相邻两元素的大小。
这样在经过每一轮比较和交换之后,最大的数字就会被移动到数组的最右边。类比一下汽水中的小气泡,如果把数组的左边看作汽水的瓶底,右边看作汽水的瓶口,数组中最大的数字每一轮都会像小气泡一样浮到了最上面,是不是裸眼3D效果都已经出来了。
2 |
5 | 4 |
8 |
7 |
9 | 1 |
6 |
3 |
2 |
4 |
5 |
8 | 7 |
9 | 1 |
6 |
3 |
(2)5 < 8,保持不变;8 > 7,交换位置
2 |
4 |
5 |
7 |
8 |
9 |
1 |
6 | 3 |
(3)8 < 9,保持不变;9 > 1,交换位置
2 |
4 |
5 |
7 |
8 |
1 |
9 |
6 |
3 |
(4)9 > 6,交换位置
2 |
4 |
5 |
7 |
8 |
1 |
6 |
9 |
3 |
(5)9 > 3,交换位置
2 |
4 |
5 |
7 |
8 |
1 |
6 |
3 |
9 |
2 |
4 |
5 |
7 |
8 |
1 |
6 |
3 |
9 |
2 | 4 |
5 | 7 |
1 |
6 |
3 |
8 | 9 |
2 | 4 |
5 |
1 |
6 |
3 | 7 |
8 | 9 |
2 |
4 | 1 |
5 |
3 |
6 | 7 |
8 | 9 |
2 |
1 | 4 |
3 |
5 |
6 | 7 |
8 | 9 |
1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
1 |
2 |
3 | 4 | 5 |
6 | 7 | 8 |
9 |
1 |
2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 |
/**
* bubbleSort
* @param data 待排序数组
*/
private int[] bubbleSort(int[] data) {
// swap 时用到的临时变量
int temp;
for (int i = 0; i < data.length - 1; i++) {
for (int j = 0; j < data.length - 1 - i; j++) {
if (data[j] > data[j + 1]) {
// swap
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
return data;
}
/**
* bubbleSort优化
* @param data 待排序数组
* 如果某一轮已经有序,则提前结束
*/
public int[] bubbleSort(int[] data) {
int temp;
// 标记是否有序
boolean isSorted;
for (int i = 0; i < data.length - 1; i++) {
// 每一轮开始 isSorted 初始值都置为 true
isSorted = true;
for (int j = 0; j < data.length - 1 - i; j++) {
if (data[j] > data[j + 1]) {
// swap
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
// 如果进行了交换,意味着数组还不是有序的,isSorted 置为 false
isSorted = false;
}
}
if (isSorted) {
break;
}
}
return data;
}
4 |
3 | 2 | 1 | 5 |
6 | 7 | 8 | 9 |
3 |
4 | 2 |
1 | 5 |
6 | 7 | 8 | 9 |
(2)4 > 2,交换位置
3 |
2 |
4 |
1 |
5 |
6 | 7 | 8 | 9 |
(3)4 > 1,交换位置
3 |
2 | 1 | 4 |
5 |
6 | 7 |
8 | 9 |
/**
* bubbleSort优化
* @param data 待排序数组
* 每一轮排序后,记录最后一次元素交换的位置,该位置即为无序数组和有序数组的边界位置
*/
private int[] bubbleSort(int[] data) {
int temp;
boolean isSorted;
// 每次交换的位置
int lastChangeIndex = 0;
// 无序数组和有序数组的边界,内循环中每次只需比较到这里为止,第一轮边界值为数组最后一个值
int sortBorder = data.length - 1;
for (int i = 0; i < data.length - 1; i++) {
isSorted = true;
for (int j = 0; j < sortBorder; j++) {
if (data[j] > data[j + 1]) {
// swap
temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
isSorted = false;
// lastChangeIndex 更新为每次交换的位置
lastChangeIndex = j;
}
}
// 此时 lastChangeIndex 表示每一轮中最后一次交换的位置,即此时无序数组和有序数组的边界值,将它赋值给 sortBorder
sortBorder = lastChangeIndex;
if (isSorted) {
break;
}
}
return data;
}
-
最优时间复杂度:O(n) -
在最理想的情况下,即待排序数组本来就是有序的,用上述冒泡排序优化代码来实现,其实我们只需要遍历 1 次就可以了。假定待排序数组长度为 n,那么最优时间复杂度即为 O(n)。 -
最坏时间复杂度:O(n^2) -
平均时间复杂度:O(n^2)
-
整个过程都是原地排序,并没有用到其它辅助的空间。
----------End----------
以上是关于从冒泡排序开始的主要内容,如果未能解决你的问题,请参考以下文章