常見的排序算法——JS實現
阿新 • • 發佈:2019-04-04
一位 歸並 lan pre pso uic tar ron epo
圖片來源:常用排序算法總結(一) (博主對幾種算法的講解很詳細)
一、冒泡排序
1 function bubbleSort(arr) { 2 var i = arr.length, j; 3 while (i > 0) { 4 for (j = 0; j < i - 1; j++) { 5 if (arr[j] > arr[j + 1]) { 6 var temp = arr[j]; 7 arr[j] = arr[j + 1];8 arr[j + 1] = temp; 9 } 10 } 11 i--; 12 } 13 return arr; 14 }
二、快速排序
1 function quickSort(array) { 2 function sort(arr, left = 0, right = arr.length - 1) { 3 if (left >= right) {4 return; 5 } 6 var key = arr[right]; 7 var i = left, j = right; 8 while (i < j) { 9 while (i < j && arr[i] < key) { 10 i++; 11 } 12 arr[j] = arr[i];13 while (i < j && arr[j] > key) { 14 j--; 15 } 16 arr[i] = arr[j]; 17 } 18 arr[j] = key; 19 sort(arr, left, j - 1); 20 sort(arr, j + 1, right); 21 } 22 var newArr = array.concat(); // 為了保證這個函數是純函數拷貝一次數組 23 sort(newArr); 24 return newArr; 25 }
三、插入排序
1 function insertSort(arr) { 2 var resultArr = new Array(); 3 resultArr.push(arr[0]); 4 for (var i=1; i<arr.length; i++){ 5 for (var j=0; j<i; j++){ 6 if (arr[i] <= resultArr[j]){ 7 resultArr.splice(j, 0, arr[i]); 8 break; 9 } else if (j === i - 1){ 10 resultArr.push(arr[i]); 11 } 12 } 13 } 14 return resultArr; 15 }
四、希爾排序
1 function shellSort(arr) { 2 var len = arr.length; 3 // fraction是增量,從長度的一半開始,遞減一半 4 for (var fraction = Math.floor(len/2); fraction>0; fraction = Math.floor(fraction/2)){ 5 // i是增量塊中的最後一位 6 for (var i = fraction; i<len; i++){ 7 // j是與i對應的增量塊中的前一位,j的數據大於增量塊中的後一位時交換,j遞減一個增量,依次往前 8 for (var j = i-fraction; j>=0&&arr[j]>arr[j+fraction]; j-=fraction){ 9 var temp = arr[j]; 10 arr[j] = arr[j+fraction]; 11 arr[j+fraction] = temp; 12 } 13 } 14 } 15 return arr; 16 }
五、選擇排序
1 function selectSort(arr) { 2 var minIndex; 3 var resultArr = new Array(); 4 while (arr.length > 0) { 5 minIndex = 0; 6 for (var j = 1; j < arr.length; j++) { 7 if (arr[j] < arr[minIndex]) { 8 minIndex = j; 9 } 10 } 11 resultArr.push(arr[minIndex]); 12 arr.splice(minIndex, 1); 13 } 14 return resultArr; 15 }
六、堆排序
堆排序詳解 (博主詳細講解了堆排序的過程)
1 // 交換兩個節點 2 function swap(arr, i, j) { 3 var temp = arr[i]; 4 arr[i] = arr[j]; 5 arr[j] = temp; 6 } 7 // 創建大頂堆:i為父節點位置 8 function heapCreate(arr, i, length) { 9 // 遍歷i的子節點 10 for (var j=i*2+1; j<length; j=j*2+1){ 11 var f = (j-1)/2; // j對應的父節點 12 var temp = arr[f]; 13 // 獲取兩個字節點最大的元素下標 14 if (j+1<length && arr[j]<arr[j+1]){ 15 j++; 16 } 17 // 使父節點是最大值 18 if (temp < arr[j]){ 19 swap(arr, f, j); 20 } else { 21 break; 22 } 23 } 24 } 25 // 堆排序 26 function heapSort(arr) { 27 // 初始化堆 28 for (var i=Math.floor(arr.length/2-1); i>=0; i--){ 29 // 從第一個父節點開始,判斷父節點與子節點的大小,令父節點大於子節點 30 heapCreate(arr, i, arr.length); 31 } 32 // 排序 33 for (var j=arr.length-1; j>0; j--){ 34 // 將堆頂的元素(最大)與最後一位交換 35 swap(arr, 0, j); 36 // 將交換後的堆重新創建大頂堆(除有序的元素外) 37 heapCreate(arr, 0, j); 38 } 39 return arr; 40 }
七、歸並排序
1. 遞歸
1 // 比較兩個序列,對其歸並排序 2 function merge(left, right) { 3 var temp = new Array(); 4 while (left.length>0 && right.length>0){ 5 if (left[0] < right[0]){ 6 temp.push(left.shift()); 7 } else { 8 temp.push(right.shift()); 9 } 10 } 11 return temp.concat(left, right); 12 } 13 // 遞歸 14 function mergeSort(arr) { 15 if ((arr.length === 1)){ 16 return arr; 17 } 18 var left = arr.slice(0, Math.floor(arr.length/2)); 19 var right = arr.slice(Math.floor(arr.length/2)); 20 return merge(mergeSort(left), mergeSort(right)); 21 }
2. 叠代
1 // 比較兩個序列,對其歸並排序 2 function merge(left, right) { 3 var temp = new Array(); 4 while (left.length>0 && right.length>0){ 5 if (left[0] < right[0]){ 6 temp.push(left.shift()); 7 } else { 8 temp.push(right.shift()); 9 } 10 } 11 return temp.concat(left, right); 12 } 13 // 叠代 14 function mergeSort(arr) { 15 if ((arr.length === 1)){ 16 return arr; 17 } 18 var temp = new Array(); 19 for (var i=0; i<arr.length; i++){ 20 temp.push([arr[i]]); 21 } 22 temp.push([]); //防止下面j+1時溢出 23 for (var group=arr.length; group>1; group=Math.floor((group+1)/2)) { 24 for (var k=0, j=0; j<group; k++, j+=2){ 25 temp[k] = merge(temp[j], temp[j+1]); 26 } 27 // j是遞增2的,k的值比arr.length小,遺留下來的k後面的數據必須清空 28 temp[k] = []; 29 } 30 return temp[0]; 31 }
常見的排序算法——JS實現