递归方法在JS中受到了堆栈深度的限制,在数目特别大的时候会抛出异常,所以JS使用的归并排序需要使用非递归的版本。
// non in-place
mergeSort = function(source){
const mergeArray = function(left,right){
var result = [];
while(left.length * right.length > 0){
left[0]>right[0]?result.push(right[0]):result.push(left[0]);
}
result = result.concat(left,right);
if(left.length) left.length = 0;
if(right.length) right.length = 0;
return result;
}
var mergeList = [];
for(let i = 0;i<source.length;i++){
var temp = [];
temp.push(source[i])
mergeList.push(temp);
}
while(mergeList.length>1){
for(let i = 0; i<Math.floor(mergeList.length/2);i++){
mergeList[i]=mergeArray(mergeList[i],mergeList[mergeList.length-1-i]);
}
mergeList.length = Math.ceil(mergeList.length/2);
}
return mergeList[0];
}
// in-place
Array.prototype.mergeSort = function () {
var mergeArray = function (arr1, arr2) {
var result = [];
if (!(arr1 instanceof Array)) {
arr1 = [arr1];
}
if (!(arr2 instanceof Array)) {
arr2 = [arr2];
}
while (arr1.length * arr2.length > 0) {
if (arr1[0] > arr2[0]) {
result.push(arr2.shift());
} else {
result.push(arr1.shift());
}
}
result = result.concat(arr1, arr2)
if (arr1.length > 0) {
arr1.length = 0;
}
if (arr1.length > 0) {
arr1.length = 0;
}
return result;
}
while (this.length > 1) {
for (let i = 0; i < Math.floor(this.length / 2); i++) {
this[i] = mergeArray(this[i], this[this.length - 1 - i]);
}
this.length = Math.ceil(this.length / 2);
}
for (var i = 1; i <= this[0].length; i++) {
this[i] = this[0][i - 1];
}
this.shift();
}