先写一个交换位置的方法,以后会用到:
function swap(a, b, arr) {
let temp = arr[a]
arr[a] = arr[b]
arr[b] = temp
}
冒泡排序的基本写法如下:
function bubble(arr) {
let len = arr.length;
for (let i = len; i > 0; i--) {
for (let j = 1; j < i; j++) {
let a = arr[j - 1]
let b = arr[j]
if (a > b) {
swap(j, j - 1, arr)
}
}
}
return arr
}
怎么优化代码呢???
- 我们知道冒泡排序会比较n-1轮,每轮要比较n-1次,如果是已经排序好的数字,也会这样重复的比较,所以我们可以减少比较的次数。
function bubble(arr) {
let i = arr.length;
while (i > 0) {
let pos = 0;
for (let j = 1; j < i; j++) {
if (arr[j - 1] > arr[j]) {
pos = j;
swap(j - 1, j, arr)
}
}
i = pos
}
}
传入[ 1, 2, 3, 4 ]数组时我们只会比较一轮,减少了无用的重复操作。如果部分是有序的字数,这样优化很好。
- 传统冒泡排序中每一趟排序操作只能找到一个最大值或最小值,我们考虑利用在每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大者和最小者) , 从而使排序趟数几乎减少了一半。
function bubble(arr) {
let low = 0;
let high = arr.length - 1;
let j;
while (low < high) {
// 大的值往右冒泡
for (j = low; j < high; j++) {
if (arr[j] > arr[j + 1]) {
swap(j, j + 1, arr)
}
}
high--;
// 小的值往左冒泡
for (j = high; j > low; j--) {
if (arr[j] < arr[j - 1]) {
swap(j, j - 1, arr)
}
}
low++;
}
}