先寫一個交換位置的方法,以後會用到:
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++;
}
}