zoukankan      html  css  js  c++  java
  • 归并排序

    归并排序

    1. 把 2 个及以上的有序子序列,"归并" 成一个有序序列
    2. 内部排序中,多采用 二路 归并排序
    3. 整个归并排序只需要 logN 躺
    • 基本思想:

      1. 切分步骤:先将大数组,拆分成 2 组,然后 2 组再拆分,直到元素个数为 1,
      2. 合并步骤:接着两个 单一元素比较合并,合并完再合并 两个 二元素,接着 两个 四元素
    • 具体思路:

      1. 递归切分数组
      2. 若当前数组 数量小于 1,无需排序,直接返回结果
      3. 否则当前数组分成 2 个子数组,递归排序这 2 个子数组
      4. 在子数组排序结束后,将子数组的结果归并成排好序的数组
    • 关键问题:

      1. 如何将两个有序序列,合并成一个?
        • 分别用指针指向两个不同的有序序列,比较当前指针所在的元素,哪个小,移出哪个,且移出所在指针前进一位重复比较
        • 若 一方 已为空,则直接把另一方有序序列,全部接在后面
    • 时间复杂度: O(n logn)

    • 空间复杂度: O(n),因为需要一个与原始序列同样大小的辅助序列

    let list = [8, 4, 5, 7, 1, 3, 6, 2];
    
    let temp = [];
    
    function MergeSort(list, start, end) {
      if (end - start < 1) return; //为了细化分到单个元素,所以不需要 =
    
      // 分 (大化小)
      let mid = Math.floor((start + end) / 2);
      MergeSort(list, start, mid);
      MergeSort(list, mid + 1, end);
    
      // 治 (从单个元素开始合并成有序)
      Merge(list, start, mid, end, temp);
    }
    
    MergeSort(list, 0, list.length - 1);
    console.log(list);
    
    function Merge(list, start, mid, end, temp) {
      let l_start = start;
      let r_start = mid + 1;
      let i = 0;
    
      // mid实则为 l_end, end实则为r_end
      while (l_start <= mid && r_start <= end) {
        //比较 左右两边,将其按顺序塞进 temp数组里
        if (list[l_start] < list[r_start]) {
          temp[i++] = list[l_start++];
        } else {
          temp[i++] = list[r_start++];
        }
      }
    
      //如果 一边完了,另一边还有的话,直接全部塞进 temp里
      while (l_start <= mid) {
        temp[i++] = list[l_start++];
      }
    
      while (r_start <= end) {
        temp[i++] = list[r_start++];
      }
    
      //temp已经是有序了,这里利用temp将list对应的下标调整为有序
      //这样做了,才可以让 下一次递归是建于 list有序 的基础之上
      i = 0;
      while (start <= end) {
        list[start++] = temp[i++];
      }
    }
    
  • 相关阅读:
    NOI2021 题解
    CF605E Intergalaxy Trips
    P4762 [CERC2014]Virus synthesis
    特征向量与特征值
    uoj
    NOI 2021
    [NOI2011] NOI 嘉年华 【DP】
    CF1264D(组合数)
    绝对不咕
    题解 SP11985 【GOT
  • 原文地址:https://www.cnblogs.com/pengnima/p/12626580.html
Copyright © 2011-2022 走看看