Iterative sorting algorithms
- bubble sort
- insertion sort
- selection sort
Bubble sort
將陣列中相鄰元素兩兩做比較,若第一個元素大於第二個元素,兩者順序互換,依序重複此步驟到最後兩個元素,可以確保最大元素被放在陣列的尾端
略過已經排序完的尾端元素,重複上述步驟,即為泡沫排序法,時間複雜度為 O(n²)
以 [3, 7, 5, 1]
為例:
[3, 7, 5, 1]
從 index 0 開始- 3 小於 7,略過
- 7 大於 5,互換
[3, 5, 7, 1]
- 7 大於 1,互換
[3, 5, 1, 7]
- 有換過順序,繼續下一輪
[3, 5, 1, 7]
從 index 0 開始,忽略已排序元素 (7 為已排序)- 3 小於 5,略過
- 5 大於 1,互換
[3, 1, 5, 7]
- 有換過順序,繼續下一輪
[3, 1, 5, 7]
(5, 7 為已排序)- 3 大於 1,互換
[1, 3, 5, 7]
- 有換過順序,繼續下一輪
- 3 大於 1,互換
[1, 3, 5, 7]
(3, 5, 7 為已排序)- 沒有比對元素,即完成排序
function bubbleSort(nums) {
let counter = 0;
let swapped = false;
do {
swapped = false;
counter += 1;
for (let i = 0; i < nums.length - counter; i++) {
if (nums[i] > nums[i + 1]) {
const lesser = nums[i + 1];
nums[i + 1] = nums[i];
nums[i] = lesser;
swapped = true;
}
}
} while(swapped);
return nums;
}
bubbleSort([3, 7, 5, 1]);
Insertion sort
取自維基百科
它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入。插入排序在實現上,通常採用 in-place 排序(即只需用到
O(1)
的額外空間的排序),因而在從後向前掃描過程中,需要反覆把已排序元素逐步向後挪位,為最新元素提供插入空間。
插入排序法的時間複雜度為 O(n²)
下方程式碼以 [3, 7, 5, 1]
為例,先將 3 視為已排序的部分:
- 從 index 1,依序向左掃瞄
- 7 大於 3,插入的 index 為 1
[3, 7, 5, 1]
- 7 大於 3,插入的 index 為 1
- 從 index 2 ,依序向左掃瞄
- 5 小於 7,將 7 向右移
[3, 7, 7, 1]
- 5 大於 3,插入位置 3 的右側,即為 index 1
[3, 5, 7, 1]
- 5 小於 7,將 7 向右移
- 從 index 3 ,依序向左掃描
- 1 小於 7,7 向右移
[3, 5, 7, 7]
- 1 小於 5,5 向右移
[3, 5, 5, 7]
- 1 小於 3,3 向右移
[3, 3, 5, 7]
- 找到 1 的插入位置為 index 0
[1, 3, 5, 7]
- 1 小於 7,7 向右移
export default function insertionSort(arr: Array<number>): Array<number> {
// 從 index 1 開始
for (let i = 1; i < arr.length; i++) {
// 暫存待排序的元素
const numberToInsert = arr[i];
// 紀錄插入排序的指標
let j = i - 1;
// 依序往前比對
while (j >= 0 && arr[j] > numberToInsert) {
// 先將元素往右移
arr[j + 1] = arr[j];
// 更新插入排序指標
j--;
}
// 將待排序元素更新至插入排序指標
arr[j + 1] = numberToInsert;
}
return arr;
}
Selection sort
取自維基百科
在未排序的序列中找到最小元素,放到已排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢
選擇排序法的時間複雜度為 О(n²)
以 [3, 5, 7, 1]
為例:
- 從 index 0 開始,找出最小值
- 3 小於 5,最小值為 3
- 3 小於 7,最小值為 3
- 3 大於 1,最小值為 1
- 將 1 放到最左側
[1, 3, 5, 7]
。將 1 視為已排序序列
- 在剩餘元素
[3, 5, 7]
中找出最小值,放到已排序序列的右側- 3 小於 5,最小值為 3
- 3 小於 7,最小值為 3
- 將 3 放到已排序序列的右側 (index 相同可以忽略)
- 在剩餘元素
[5, 7]
中找出最小值,放到已排序序列的右側- 5 小於 7,最小值為 7
- 將 5 放到已排序序列的右側 (index 相同可以忽略)
實作的範例程式碼如下:
indexOfMin
表示已排序序列的末尾位置,如果與未排序序列最小值 index 相同,則可忽略
比較該位置與已排序序列末尾位置,若不相同則將兩者進行替換
function selectionSort(nums) {
for (let i = 0; i < nums.length - 1; i++) {
let indexOfMin = i;
for(let j = i + 1; j < nums.length; j++) {
if (nums[j] < nums[indexOfMin]) {
indexOfMin = j;
}
}
if (i !== indexOfMin) {
const lesser = nums[indexOfMin];
nums[indexOfMin] = nums[i];
nums[i] = lesser;
}
}
return nums;
}
selectionSort([3, 7, 5, 1]);