当前位置: 首页 > article >正文

数据结构与算法之排序: 归并排序 (Javascript版)

排序

  • 排序:把某个乱序的数组变成升序或降序的数组 (这里用数组来做举例)

归并排序

  • 该排序属于 分治 策略
  • 将一个问题分解为两个问题来计算,计算完成之后,就会得到子任务的解,这些解不是最终问题的解,还需要merge起来

算法实现

// 归并排序
Array.prototype.mergeSort = function() {
    // 递归自身拆分
    const rec = (arr) => {
        let len = arr.length;
        if(len === 1) {
            return arr;
        }
        let m = Math.floor(len / 2); // 取中值
        let l = arr.slice(0, mid);
        let r = arr.slice(0, len);
        let lo = rec(l); // 递归下去,就变成了一个数组成的数组,最终有序 o => order
        let ro = rec(r); // 同上

        // 上面递归完成,开始进行合并操作
        let res = []; // 最终合并后的数组
        let lol = lo.length; // 左边数组长度
        let lor = ro.length; // 右边数组长度
        while(lol || lor) {
            if(lol && lor) {
                res.push(lo[0] < ro[0] ? lo.shift() : ro.shift())
            } else if(lol) {
                res.push(lo.shift())
            } else if(rol) {
                res.push(ro.shift())
            }
        }
        return res;
    }
    // 获取递归结果
    const r = rec(this);
    // 将有序数组拷贝到this上
    r.forEach((n, i) => {this[i] = n;});
}

let arr = [5,4,3,2,1]
arr.insertionSort()
console.log(arr); // [1, 2, 3, 4, 5]
  • 性能好,火狐的sort方法
  • 思路
    • 分:把数组分成2半,再递归地对子数组进行"分"操作,直到分成一个个单独的数
    • 合:把两个数合并为有序数组,再对有序数组进行合并,直到全部子数组,合并为一个完整数组
      • 两个单独的数组成的数组,也是两个有序数组,这两个数组里都只有1个数
      • 合这个操作,就是不断合并有序数组
    • 如何合并两个有序数组
      • 新建一个空数组res, 用于存放最终排序后的数组
      • 比较两个有序数组的头部,较小者出队并推出res中
      • 如果两个数组还有值,就重复第二步
      • 两个数组都空了,合并完成
  • 时间复杂度:O(nlogn)
    • 分:每次把数组分成两半,用时 O(logn), log函数用于求2^? = n, 自然要?=log_2 n, 即 O(logn)
      • 注意,凡是分的操作,基本都是logn
    • 合:O(n), 一个while循环体

http://www.kler.cn/news/106897.html

相关文章:

  • Jenkins入门级安装部署
  • 轻量封装WebGPU渲染系统示例<1>-彩色三角形(源码)
  • MySQL存储过程与函数
  • SOLIDWORKS® 2024 新功能 - SIMULATION
  • 人生岁月年华
  • Pytorch - 数据增广
  • Unity3D 如何用unity引擎然后用c#语言搭建自己的服务器
  • C# 基于腾讯云人脸核身和百度云证件识别技术相结合的 API 实现
  • ​ iOS自动混淆测试处理笔记
  • 干式电抗器的尺寸和重量对系统有什么影响?
  • Redis快速上手篇八(redission分布式锁)
  • AXI-Stream协议详解(3)—— AXI4-Stream IP核原理分析
  • 使用一个Series序列减去另一个Series序列Series.subtract()
  • buuctf_练[GYCTF2020]FlaskApp
  • UVa10976 Fractions Again?!(分数拆分)
  • shell实验
  • Linux常用命令——chpasswd命令
  • 2.19每日一题(分段函数求定积分)
  • MATLAB算法实战应用案例精讲-【目标检测】YOLOV8
  • C++STL----list的使用
  • 解决eslint与prettier在代码格式上的冲突
  • C++系列之list的模拟实现
  • SpringBoot | SpringBoot中实现“微信支付“
  • Flask Run运行机制剖析
  • Kafka - 3.x 副本不完全指北
  • 工业相机常见的工作模式、触发方式
  • linux可用内存不足如何排查清理
  • easyExcel按模板填充数据,处理模板列表合并问题等,并导出为html,pdf,png等格式文件demo
  • github中.gitignore不起作用啦
  • 蓝桥算法赛(铺地板)