<script type="text/javascript"> /* 歸併排序:就是指將表對半拆分到最後剩下 2個元素,然後比較這個兩個元素大小,排序好做爲一個元素,和本身同級別的元素 再比較,排序,合併,最後生成一個序列表 歸併排序其實要作兩件事: (1)「分解」——將序列每次折半劃分。 (2)「合併」——將劃分後的序列段兩兩合併後排序。 */ function MereSort(L) { MSort(L, L, 0, L.length-1); } //s爲小下標,t爲最終下標 首先進行分解 function MSort(SR,TR1,s,t) { var m; var TR2=[]; if (s == t) TR1[s] = SR[s]; else { m = Math.floor((s + t) / 2);//將SR[s...t]平分SR[s...m]和SR[m+1...t]; MSort(SR, TR2, s, m);//遞歸將SR[s...m]歸併爲有序的TR2[s...m] MSort(SR, TR2, m + 1, t);//遞歸將SR[m+1...t]歸併爲有序TR2[m+1..t]; Merge(TR2, TR1, s, m, t);//將TR2[s...m]和TR2[m+1...t]歸併到TR[s...t]; } } function Merge(SR,TR,i,m,n) {//將有序的SR[i....m]和SR[m+1...n]歸併爲有序的TR[i..n] var j,k; for (j = m + 1, k = i; i <= m && j <= n; k++) {//將SR中的記錄從小到大歸併到TR中 if (SR[i] < SR[j]) TR[k] = SR[i++]; else TR[k] = SR[j++]; } while (i <= m) { TR[k++] = SR[i++];//將剩餘的SR[i...m]複製到TR[K+i] } while (j <= n) { TR[k++] = SR[j++];//將剩餘的SR[j...n]複製到TR[k+j] } } /*因爲遞歸的性能有限,這裏實現非遞歸歸併排序*/ function MergeSort2(L) { var TR = []; var k = 1; while (k < L.length-1) { MergePass(L, TR, k, L.length);//首先倆倆歸併成一個元素 k=2*k; MergePass(TR,L,k,L.length);//新的兩兩再歸併 k=2*k; } } /*s爲歸併元素的個數,n爲總元素的個數 */ function MergePass(SR, TR, s, n) {//將SR[]中相鄰長度TR[]兩兩歸併到TR中 var i = 0, j; while(i<=n-2*s){// 由於若是i>n-2s,那麼i+s,i+s+1,i+s+1+s>n越界了 不必比較 即:i+s+s<=n Merge(SR, TR, i, i + s - 1, i + 2 * s - 1);//調用上面進行兩兩歸即:SR[0]與SR[1] SR[2]與SR[3] 。。。。SR[n-2]與SR[n-1]; i = i + 2 * s; } if (i < n - s + 1) {//歸併最後兩個序列 Merge(SR, TR, i, i + s - 1, n-1); } else {//若最後只剩下單個子序列 for (j = i; j < n; j++) TR[j] = SR[j]; } } var l = [1, 4, 2, 5, 7, 8, 9, 0, 3, 2]; //MereSort(l); MergeSort2(l); console.log(l); </script>
建議你們使用非遞歸歸併排序 ,效率較高一些!,它避免了遞歸時深度爲logn的空間,空間複雜度爲O(n)!兩種方法時間複雜度都爲O(nlogn)!javascript
和你們一塊兒學習了,下一篇 快速排序吧java