JavaScript实现归并排序-递归法与非递归法

1.归并排序

将已有的序列的子序列合并,得到完全有序的序列;

即先使每个子序列有序,再使子序列有序 喏将两个有序表合成一个有序表则称为二路归并

//定义组的交换
let merge=(left,right)=>{
	var result=[];
	while(left.length>0&&right.length>0){
		if(left[0]<=right[0]){
			result.push(left.shift());
		}else{
			result.push(right.shift());
		}
	}
	return result.concat(left).concat(right);
}
//进行递归
let margeSort=(arr)=>{
	var len=arr.length;
	if(len<2){
		return arr;
	}
	var center=Math.floor(len/2);
	var  left=arr.slice(0,center);//slice方法不会改变原数组
	var right=arr.slice(center);
	return merge(margeSort(left),margeSort(right));
}
var arr=[8,7,6,5,4,3,2,1,10,9];
var a=margeSort(arr);
console.log(a);
//递归的方法

2.非递归方法进行排序

//迭代归并排序
let merge=(arr,temp,left,middle,right)=>{
	const leftEnd=middle-1;//获得左边数组的结束位置(通过右边数的起始位置获得左边数的结束位置)
	while(left<=leftEnd&&middle<=right){//判断指针是否越界
		if(arr[left]<=arr[middle]){//如果左边数组的最左边小于等于右边数组的最左边
			temp[left+middle-leftEnd-1]=arr[middle++];//将右边数组最小的存放temp数组中(temp的初始值为null)
		}else{
			temp[left+middle-leftEnd-1]=arr[left++];//将左边数组最小的存放在temp数组中(temp的初始值为null)
		}
	}
	while(left > leftEnd && middle < right){ // 如果左边数组放完了,右边数组还有元素。
    temp[left + middle - leftEnd -1] = arr[middle++]; // 那么依次将右边数组剩余的元素放入 temp 。
}
  	while(left <= leftEnd && middle >= right){ // 如果右边数组放完了,左边数组还有元素
    temp[left + middle - leftEnd -1] = arr[left++]; // 那么依次将左边数组剩余的元素放入 temp 。
  }
}
//深度
let mergePass=(arr=[],temp=new Array(arr.length),N=arr.length,length=1)=>{//将每个元素看成是数组长度为一
	let t;//迭代的深度
	for(t=0;Math.pow(2,t)<N;t++,length*=2){//每次跳过的长度翻倍
		const even = t%2 === 0; // 复用 arr 和 temp 来回赋值。
		for (let left = 0;  left < N; left += 2 * length) { // 左边数组起始位置 left 从0开始。
      	const middle = left + length < N ? left + length : left; // 右边数组起始位置 middle 就是left + 一个数组长度length 但是不要超过 N 。
      	const right = left + (2 * length) < N ? left + (2 * length) : N; // 右边界 right 就是 left + 两个数组长度。
      	merge(even ? arr : temp, even ? temp : arr, left, middle, right); // 合并每两个相邻的数组。
    }
	}
	merge(arr, temp, 0, Math.pow(2,t-1), N); // 上面的迭代深度始终少一次在这里补足。
  arr = temp; // 将稳定的数组赋值给 arr 释放掉 temp 。
  return arr; // 返回 arr 。
}
var arr=[8,7,6,5,4,3,2,1,10,9];
var a=mergePass(arr);
console.log(a);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值