1. 程式人生 > >常見的排序算法——JS實現

常見的排序算法——JS實現

一位 歸並 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實現