js实现归并排序(mergeSort)

理解归并排序

归并排序是一种基于分治思想的排序算法,它将一个待排序的序列分为两个子序列,分别对子序列进行排序,然后将排好序的子序列合并成一个有序的序列。这个过程可以递归地进行,直到序列被划分为只有一个元素时停止递归。

在归并排序的过程中,将序列分为两个子序列的操作称为分治,合并两个有序子序列为一个有序序列的操作称为归并。分治和归并是归并排序的核心操作。

具体而言,归并排序的过程如下:

  1. 将序列递归地分为左右两个子序列,直到每个子序列只有一个元素。
  2. 对左右两个子序列进行归并排序,得到两个有序子序列。
  3. 合并两个有序子序列,得到一个有序序列。

归并排序的时间复杂度为 O(nlogn),相较于其他排序算法具有较好的稳定性和效率。

归并排序实现代码

/**
 * 归并排序
 * @param {要排序的数组} arr
 */
function mergeSort(arr) {
  if (arr.length > 1) {
    const middle = Math.floor(arr.length / 2);
    const left = mergeSort(arr.slice(0, middle));
    const right = mergeSort(arr.slice(middle, arr.length));
    arr = merge(left, right);
  }
  return arr;
}
// 合并左分支数组和右分支数组,左分支和右分支在自己数组里面已经是有序的。所以就方便很多。
function merge(left, right) {
  // 剪枝优化
  if (left[left.length - 1] <= right[0]) {
    return left.concat(right);
  }
  if (right[right.length - 1] <= left[0]) {
    return right.concat(left);
  }

  let result = [];
  let leftIndex = 0;
  let rightIndex = 0;

  while (leftIndex < left.length && rightIndex < right.length) {
    if (left[leftIndex] <= right[rightIndex]) {
      result.push(left[leftIndex]);
      leftIndex++;
    } else {
      result.push(right[rightIndex]);
      rightIndex++;
    }
  }
  // 将剩余数据拷贝至result
  if (leftIndex < left.length) {
    result = result.concat(left.slice(leftIndex));
  } else {
    result = result.concat(right.slice(rightIndex));
  }
  return result;
}

实现代码详细解说

这段代码实现了归并排序,具体过程就是将待排序的数组一分为二,分别对左右两部分进行排序,然后再将排好序的两部分合并起来,这样就能得到一个完整有序的数组。

在代码中,mergeSort函数是递归调用自己实现的排序函数。如果数组的长度大于1,就将其一分为二,分别对左右两部分进行递归排序,并最终通过merge函数将排好序的两部分合并为一个完整的有序数组。如果数组长度小于等于1,就直接返回该数组。

merge函数的作用就是将两个有序数组合并为一个有序数组。代码首先进行了剪枝优化,判断左右两个数组是否已经有序,如果是的话就直接将它们合并起来返回。如果不是,就使用两个指针leftIndexrightIndex分别遍历左右两个数组,比较它们的元素大小,将较小的元素依次放入result数组中。当其中一个数组遍历完了之后,就将另一个数组中剩余的元素依次拷贝至result数组的末尾。

最后,在代码末尾,我们调用了mergeSort函数并传入一个待排序的数组,最终得到的输出结果就是该数组排序后的结果。

你可能感兴趣的:(javascript,排序算法,算法)