前端实现归并排序的思路

function mergeSort(arr) {  
  if (arr.length <= 1) {  
    return arr;  
  }  
    
  const mid = Math.floor(arr.length / 2);  
  const left = arr.slice(0, mid);  
  const right = arr.slice(mid);  
    
  return merge(mergeSort(left), mergeSort(right));  
}  
  
function merge(left, right) {  
  const result = [];  
  let i = 0;  
  let j = 0;  
    
  while (i < left.length && j < right.length) {  
    if (left[i] <= right[j]) {  
      result.push(left[i]);  
      i++;  
    } else {  
      result.push(right[j]);  
      j++;  
    }  
  }  
    
  return [...result, ...left.slice(i), ...right.slice(j)];  
}

几个想法说明下:
1 关于merge(mergeSort(left), mergeSort(right));的想法由来
2 [...result, ...left.slice(i), ...right.slice(j)];ES6用法的使用

1 关于merge(mergeSort(left), mergeSort(right));的推导
归并排序,基本查查资料都知道采用的是分治的思想。两个关键点:分和归
实现的思路整体上是这样的:把一个数组分成两个数组(假设这两个数组已经有序了,这里很关键,如果不是有序的,你还要在分,这里就是递归的思想),然后进行归,也就是合并。但是怎么合并呢?很多人查看资料,也知道是通过遍历比对。我们先不管那么多,假设我们有个函数merge,实现合并的。敲黑板!!重点来了。我们从分解到合并的过程,考虑简单点,假设分解后,我们的两个数组都是有序的,我们就能合并了。所以我们合并的就是原数组的两个分支,merge(left,right),这里left,right就是分解后的有序数组。那么在思考下,如果left和right不是有序的呢?是不是还要在分,然后合?所以我们最后合并的是left和right分到最后一层后的合。即merge(mergeSort(left),mergeSort(right))

这里我在演绎下推到过程:
递归有几个步骤:找到递推体,找到退出条件
我们高中学的f(n)=f(n-1)+1就是一种递归
1 找到递归体

//首先我们写一个函数,这个函数就是把数组分开,然后合并的
function mergeSort(arr){
	//把数组分成两个left/right进行合并
	const mid = Math.floor(arr.length / 2);  
    const left = arr.slice(0, mid);  
    const right = arr.slice(mid);
    return merge(left,right)
}
//但是上面的有个前提,就是left/right都是有序的,要是无序的怎么办?继续自调用分
function mergeSort(arr){
	//把数组分成两个left/right进行合并
	const mid = Math.floor(arr.length / 2);  
    const left = arr.slice(0, mid);  
    const right = arr.slice(mid);
    return merge(mergeSort(left),mergeSort(right))
}
//那怎么合并呢?通过指针逐次比对两个数组的大小
function merge(left,right){
  const result = [];  
  let i = 0;  
  let j = 0;  
    
  while (i < left.length && j < right.length) {  
    if (left[i] <= right[j]) {  
      result.push(left[i]);  
      i++;  
    } else {  
      result.push(right[j]);  
      j++;  
    }  
  }  
    
  return [...result, ...left.slice(i), ...right.slice(j)]; 
}
//当什么时候不需要在分呢?有序或者只有1个数的时候
function mergeSort(arr){
	if(arr.length<2) return arr;
	//把数组分成两个left/right进行合并
	const mid = Math.floor(arr.length / 2);  
    const left = arr.slice(0, mid);  
    const right = arr.slice(mid);
    return merge(left,right)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李卓书

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值