2019-4-24
時間測試
const arr = [];
for (let i = 0; i < 100000; i++) {
const random = Math.floor(Math.random() * (100000 - 0 + 1) + 0);
arr.push(random);
}
const beginTime = +new Date();
const quickSort = this.quickSort(arr);
const endTime = +new Date();
console.log(`${endTime - beginTime}`);
複製程式碼
快排
quickSort = arr => {
if (arr.length <= 1) return arr;
const base = arr[0];
const left = [],
middle = [base],
right = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] === base) middle.push(arr[i]);
else if (arr[i] < base) left.push(arr[i]);
else right.push(arr[i]);
}
return this.quickSort(left).concat(middle, this.quickSort(right));
};
複製程式碼
普通冒泡
bubleSort = arr => {
for (let i = 0; i < arr.length - 1; i++) {
let isChanged = false;
for (let j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
isChanged = true;
}
}
if (!isChanged) break;
}
return arr;
};
複製程式碼
增加標誌點位冒泡
bubleSore2 = arr => {
let height = arr.length - 1;
while (height > 0) {
let position = 0;
for (let j = 0; j < height; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
position = j;
}
}
height = position;
}
return arr;
};
複製程式碼
正反同時冒泡
bubleSore3 = arr => {
let low = 0,
high = arr.length - 1;
while (low < high) {
// 正向遍歷找最大
for (let i = low; i <= high; i++)
if (arr[i] > arr[i + 1]) this.swap(arr, i, i + 1);
high--;
// 反向遍歷找最小
for (let j = high; j >= low; j--)
if (arr[j] < arr[j - 1]) this.swap(arr, j, j - 1);
low++;
}
return arr;
};
複製程式碼
堆排序
本質是遞迴構建完全二叉樹
交換二叉樹內容
swap = (arr, n, m) => {
[arr[n], arr[m]] = [arr[m], arr[n]];
};
複製程式碼
堆排序 遞迴尋找非葉子節點
heapSort = arr => {
const arr_length = arr.length;
if (arr_length <= 1) return arr;
// 1. 建最大堆
// 遍歷一半元素就夠了
// 必須從中點開始向左遍歷,這樣才能保證把最大的元素移動到根節點
for (let middle = Math.floor(arr_length / 2); middle >= 0; middle--) {
this.maxHeapify(arr, middle, arr_length);
}
// 2. 排序,遍歷所有元素
for (let j = arr_length; j >= 1; j--) {
// 2.1. 把最大的根元素與最後一個元素交換
this.swap(arr, 0, j - 1);
// 2.2. 剩餘的元素繼續建最大堆
this.maxHeapify(arr, 0, j - 2);
}
return arr;
};
複製程式碼
構建最大堆
maxHeapify = (arr, middle_index, length) => {
// 1. 假設父節點位置的值最大
let largest_index = middle_index;
// 2. 計算左右節點位置
const left_index = 2 * middle_index + 1,
right_index = 2 * middle_index + 2;
// 3. 判斷父節點是否最大
// 如果沒有超出陣列長度,並且子節點比父節點大,那麼修改最大節點的索引
// 左邊更大
if (left_index <= length && arr[left_index] > arr[largest_index])
largest_index = left_index;
// 右邊更大
if (right_index <= length && arr[right_index] > arr[largest_index])
largest_index = right_index;
// 4. 如果 largest_index 發生了更新,那麼交換父子位置,遞迴計算
if (largest_index !== middle_index) {
this.swap(arr, middle_index, largest_index);
// 因為這時一個較大的元素提到了前面,一個較小的元素移到了後面
// 小元素的新位置之後可能還有比它更大的,需要遞迴
this.maxHeapify(arr, largest_index, length);
}
};
複製程式碼