标签:
<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)!
和大家一起学习了,下一篇 快速排序吧
标签:
原文地址:http://www.cnblogs.com/ddcouples/p/5625087.html