資料結構與演算法--排序(冒泡、選擇、歸併、快速排序、堆排序)
阿新 • • 發佈:2018-12-11
/** * 氣泡排序 * @param arr */ function bubbleSort(arr) { let len = arr.length; for (let i =0; i < arr.len; i++) { for (let j = 0; i < len - i - 1; j++) { if (arr[j] > arr[j+1]) { [arr[j], arr[j+1]] = [arr[j+1], arr[j]]; } } } } /** * 選擇排序 * @param arr */ function selectSort(arr) { let len = arr.length, minIndex; for (let i = 0; i < len; i++) { minIndex = i; for (let j = i + 1; j < len; j++) { if (arr[j] > arr[minIndex]) { minIndex = j; } } if (i != minIndex) { [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]] } } } /** * * @param arr */ function insertionSort(arr) { let len = arr.length, j , temp; for (let i = 1; i < len; i++) { temp = arr[i]; j = i; while (j > 0 && arr[j-1] > temp) { arr[j-1] = arr[j]; j--; } arr[j] = temp; } } /** * 歸併排序:先遞迴將陣列拆分成小的陣列,然後再將小陣列排序歸併 * @param arr */ function mergeSort(arr) { let array = mergeSortRec(arr); function mergeSortRec(arr) { let len = arr.length; if (len === 1) { return arr; } let mid = Math.floor(len / 2), left = arr.slice(0, mid), right = arr.slice(mid, len); return merge(mergeSortRec(left), mergeSortRec(right)); } function merge(left, right) { let result = [], il = 0, ir = 0; while (il < left.length && ir < right.length) { if (left[il] < right[ir]) { result.push(left[il++]); } else { result.push(right[ir++]); } } while (il < left.length) { result.push(left[il++]) } while (ir < right.length) { result.push(right[ir++]) } return result; } } // 快速排序 function quickSort(arr) { quick(arr, 0, arr.length); function quick(arr, left, right) { let index = partition(arr, left, right); if (left < index - 1) { quick(arr, left, index - 1); } if (index < right) { quick(arr, index, right); } } function partition(arr, left, right) { let piort = arr[Math.floor((left + right) / 2)], i = left, j = right; while (i < j) { while (arr[i] < piort) { i++; } while (arr[j] > piort) { j--; } if (i <= j) { [arr[i], arr[j]] = [arr[j], arr[i]]; i++; j--; } } return i; } } function heapSort(arr) { function max_heapify(start, end) { // 建立父節點和子節點下標 let dad = start; let son = dad * 2; // 若子節點下標超出範圍則直接跳出函式 if (son >= end) { return; } // 比較父節點的兩個子節點,並選擇最大的 if (son + 1 < end && arr[son] < arr[son + 1]) { son++; } // 如果父節點小於子節點,則交換對應的值,再繼續子節點和孫節點的比較 if (arr[dad] < arr[son]) { // 交換 [arr[dad], arr[son]] = [arr[son], arr[dad]]; max_heapify(son, end); } } let len = arr.length; // 初始化,i 從最後一個父節點開始調整 for (let i = Math.floor(len / 2) - 1; i >= 0; i--) { max_heapify(i,len); } // 現將第一個元素和已構建成的最大堆(陣列第一個元素)交換,再重新調整,直到排序完畢 for(let i = len - 1; i > 0; i++) { [arr[0], arr[i]] = [arr[i], arr[0]]; max_heapify(0, i); } }