一、实现冒泡排序
冒泡排序就像鱼儿吐泡泡一样,从小到大,也暗示着排列的顺序是从小到大;
核心思想是依次比较前后位置元素的大小,哪个大哪个就放后面,这样一轮下来,最后一个位置一定是最大的;这里的最后一位不用继续比较了,因为倒数第二位就是与它比较;
比如这是一个要排序的无规则数组:
let arr = [4, 8, 1, 9, 6, 7];
那我们安照上面的来一轮前后比较试试:
function demo(array) {
let N = array.length;
for (let i = 0; i < N - 1; i++) {
if (array[i] > array[i + 1]) {
let tmp = array[i];
array[i] = array[i + 1];
array[i + 1] = tmp;
}
}
return array;
}
得到的结果是:[ 4, 1, 8, 6, 7, 9 ]
可以看到最大的9已经在最后了,但是前面的顺序不对呀,所以我们需要再来一层遍历:
function bubbleSort(array) {
let N = array.length;
for (let i = 0; i < N - 1; i++) {
// 每轮都会把最小的放后面
// 时间复杂度为O(N**2)
for (let j = 0; j < N - 1 - i; j++) {
// 最后一个一定是最小的,所以下一次倒数第二个即可
if (array[j] < array[j + 1]) {
let tmp = array[j];
array[j] = array[j + 1];
array[j + 1] = tmp;
}
}
}
return array;
}
这里有疑问的可能是是为什么第二次for循环的进入条件是J<N-1-i,这是因为每一轮交换位置后,最后一个一定是最大的,那么下一轮只需比较到N-1-i即可;
第一次for循环的进入条件为什么又是i<N-1呢?因为,只剩一个元素时,没人和它比较l呀,所以是N-1;
二、另一种写法
function swap(array, m, n) {
let temp = array[m];
array[m] = array[n];
array[n] = temp;
}
function bubbleSort(array) {
let length = array.length;
for (let j = length - 1; j >= 0; j--) {
for (let i = 0; i < j; i++) {
if (array[i] > array[i + 1]) swap(array, i, i + 1);
}
}
return array;
}
原理是一样的,这次不过把交换位置的逻辑给抽取到swap函数里了,方便其他排序复用;
这次外层for循环就是从大到小,原理和上面是一样的;