js 排序算法(4)- 归并排序

合并函数

// 合并函数
const merge = (arr, l, m, r) => {
  // 辅助数组
  let help = [];
  // 辅助数组下标
  let i = 0;
  // 两个指针分别指向需要合并的两个数组
  let p1 = l;
  let p2 = m + 1;
  // 两个数组都没有越界
  while (p1 <= m && p2 <= r) {
    help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
  }
  // p2越界
  while (p1 <= m) {
    help[i++] = arr[p1++];
  }
  // p1越界
  while (p2 <= r) {
    help[i++] = arr[p2++];
  }
  // 拷贝回去
  for (let i = 0; i < help.length; i++) {
    arr[l + i] = help[i]; // 这个 l 很重要
  }
};
合并思路:

        定义一个辅助数组,和三个指针(一个指向辅助数组,一个指向数组1,一个指向数组2),进行比较赋值给辅助数组并进行指针移动。值得注意的是拷贝回去的时候是要从l左指针上开始拷贝

写法1 递归写法

递归函数

// 排序函数
const fn = (arr, l, r) => {
  if (l == r) return;
  let mid = l + ((r - l) >> 1);
  fn(arr, l, mid);
  fn(arr, mid+1, r);
  merge(arr, l, mid, r);
};

思路

        将数组一分为二,分别递归排序,在合并幅值回去

        递归终止条件:数组只有一个数自带顺序

写法2 迭代写法

// 迭代写法
if (arr == null || arr.length < 2) return;
let N = arr.length; 
let step = 1; // 步长
while (step < N) {
  let L = 0;
  while (L < N) {
    // 找到中间值
    let M = L + step - 1;
    if (M >= N) { // 没有右边就跳过
      break;
    }
    let R = Math.min(M + step, N - 1); // 有右边就看看够不够步长,不够步长就剩下的全部进行合并
    merge(arr, L, M, R);
    L = R + 1; // 从R在开始
  }
  if (step > N / 2) {
    break;
  }
  step *= 2; 
}

思路

        定义一个步长,对数组从左往右,逐次以步长进行分为左右数组进行合并

        特殊情况:

                        没有右边,跳过留给下一个循环合并

                        有右边,但是不够步长,直接合并

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值