注意:两种方法的实现都不改变原数组,而是生成一个新的数组。
Array.prototype.mergeSort = function(fun/*, thisArg*/) { 'use strict'; if (this === void 0 || this === null) { throw new TypeError(); } if (fun && typeof fun !== 'function') { throw new TypeError(); } var t = Object(this); var items = t.slice(0); var len = t.length >>> 0; var thisArg = arguments.length >= 2 ? arguments[1] : void 0; function merge(left, right){ var result=[], flag = false; while(left.length>0 && right.length>0){ /* if fun return true, left is smaller than right. */ flag = !fun ? left[0]<right[0] : fun.call(thisArg, left[0], right[0]); if(flag){ /* shift(): delete and return the first element from array. */ result.push(left.shift()); } else{ result.push(right.shift()); } } /* Left is smaller than right. */ return result.concat(left).concat(right); } /* Iteration count = log2(len) */ var count = Math.LOG2E * Math.log(len), k = 1, j = 1, left, right, result; while (count > 0){ result = []; j = k * 2; // k is one group length, j is two groups' length for (var i = 0; i < len ; i = i + j) { left = items.slice(i, i + k); right = items.slice(i + k, i + j ); /* console.log(left); console.log(right); console.log(result = result.concat(merge(left, right))); */ result = result.concat(merge(left, right)); } items = result; k *= 2; // group length count--; } return items; }
Array.prototype.mergeSort = function(fun/*, thisArg*/) { 'use strict'; if (this === void 0 || this === null) { throw new TypeError(); } if (fun && typeof fun !== 'function') { throw new TypeError(); } var t = Object(this); var thisArg = arguments.length >= 2 ? arguments[1] : void 0; function merge(left, right){ var result=[], flag = false; while(left.length>0 && right.length>0){ /* if fun return true, left is smaller than right. */ flag = !fun ? left[0]<right[0] : fun.call(thisArg, left[0], right[0]); if(flag){ /* shift(): delete and return the first element from array. */ result.push(left.shift()); } else{ result.push(right.shift()); } } /* Left is smaller than right. */ return result.concat(left).concat(right); } function mergeSort(items){ /* recursive method if(items.length == 1){ return items; } var middle = Math.floor(items.length/2), left = items.slice(0, middle), right = items.slice(middle); return merge(mergeSort(left), mergeSort(right)); } return mergeSort(t); }