归并排序-迭代法与递归法

注意:两种方法的实现都不改变原数组,而是生成一个新的数组。

迭代法

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);
	}

点赞