排序算法之二:归并排序 JavaScript版本

230 阅读2分钟

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个典型的应用。

基本思想:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

Ref: www.cnblogs.com/jingmoxukon…

  • 1.非递归
function Merge(array, low, mid, high) {
	let i = low; // i是第一段序列的下标
	let j = mid + 1; // j是第二段序列的下标
	let k = 0; // k是临时存放合并序列的下标
	let array2 = new Array(); // array2是临时合并序列

	// 扫描第一段和第二段序列,直到有一个扫描结束
	while (i <= mid && j <= high) {
	// 判断第一段和第二段取出的数哪个更小,将其存入合并序列,并继续向下扫描
    	if (array[i] <= array[j]) {
	    	array2[k] = array[i];
    		i++;
    		k++;
    	} else {
    		array2[k] = array[j];
    		j++;
    		k++;
    	}
	}
	// 若第一段序列还没扫描完,将其全部复制到合并序列
	while (i <= mid) {
    	array2[k] = array[i];
    	i++;
    	k++;
	}
	// 若第二段序列还没扫描完,将其全部复制到合并序列
	while (j <= high) {
    	array2[k] = array[j];
    	j++;
    	k++;
	}
	// 将合并序列复制到原始序列中
	for (k = 0, i = low; i <= high; i++ , k++) {
    	array[i] = array2[k];
	}
}
function mergePass(arr, gap) {
	let i = 0;
	//归并gap长度的两个相邻子表
	for (i = 0; i + 2 * gap - 1 < arr.length; i = i + 2 * gap) {
    	Merge(arr, i, (i + gap - 1), i + 2 * gap - 1);
	}
	//余下两个子表,后者长度小于gap
	if (i + gap - 1 < arr.length) {
    	Merge(arr, i, (i + gap - 1), arr.length - 1);
    	console.log(i, (i + gap - 1), arr.length - 1)
	}
}
function mergeSort(arr) {
	for (let gap = 1; gap < arr.length; gap = gap * 2) {
    	mergePass(arr, gap);
	    console.log(arr);
	}
}

let arr = [2, 4, 1, 9, 6, 3, 5];
mergeSort(arr);
console.log(arr);
  • 2.递归实现
function merge(arrLeft,arrRight) {
    let result = [];
    while (arrLeft.length>0 && arrRight.length>0) {
        if (arrLeft[0] < arrRight[0]) result.push(arrLeft.shift());
        else result.push(arrRight.shift());
    }
console.log(result);
    return result.concat(arrLeft).concat(arrRight);
}

function mergeSort(arr) {
    console.log(arr);
    if (arr.length==1) {
       return arr;
    } else {
        let mid = Math.floor(arr.length / 2);
        return merge(mergeSort(arr.slice(0, mid)), mergeSort(arr.slice(mid)));
    }
}
let arr = [50, 10, 20, 30, 70, 40, 80, 60];
let rr=mergeSort(arr);
console.log(arr);