面试官:说说你对归并排序的理解?如何实现?应用场景?

一、是什么

归并排序(Merge Sort)是建立归并操作上的一种有效,稳定的排序算法,该算法是采用分治法的一个非常典型的应用

将已有序的子序列合并,得到完全有序的序列,即先使每个子序列有序,再使子序列段间有序

例如对于含有 n 个记录的无序表,首先默认表中每个记录各为一个有序表(只不过表的长度都为 1)

然后进行两两合并,使 n 个有序表变为n/2 个长度为 2 或者 1 的有序表(例如 4 个小有序表合并为 2 个大的有序表)

通过不断地进行两两合并,直到得到一个长度为 n 的有序表为止

例如对无序表{49,38,65,97,76,13,27}进行归并排序分成了分、合两部分:

如下图所示:

归并合过程中,每次得到的新的子表本身有序,所以最终得到有序表

上述分成两部分,则称为二路归并,如果分成三个部分则称为三路归并,以此类推

二、如何实现

关于归并排序的算法思路如下:

  • 分:把数组分成两半,再递归对子数组进行分操作,直至到一个个单独数字

  • 合:把两个数合成有序数组,再对有序数组进行合并操作,直到全部子数组合成一个完整的数组

    • 合并操作可以新建一个数组,用于存放排序后的数组
    • 比较两个有序数组的头部,较小者出队并且推入到上述新建的数组中
    • 如果两个数组还有值,则重复上述第二步
    • 如果只有一个数组有值,则将该数组的值出队并推入到上述新建的数组中

用代码表示则如下图所示:

function mergeSort(arr) {  // 采用自上而下的递归方法
    const len = arr.length;
    if(len < 2) {
        return arr;
    }
    let middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right)
{
    const result = [];

    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }

    while (left.length)
        result.push(left.shift());

    while (right.length)
        result.push(right.shift());

    return result;
}

上述归并分成了分、合两部分,在处理分过程中递归调用两个分的操作,所花费的时间为2乘T(n/2),合的操作时间复杂度则为O(n),因此可以得到以下公式:

总的执行时间 = 2 × 输入长度为n/2sort函数的执行时间 + merge函数的执行时间O(n)

当只有一个元素时,T(1) = O(1)

如果对T(n) = 2 * T(n/2) + O(n) 进行左右 / n的操作,得到 T(n) / n = (n / 2) * T(n/2) + O(1)

现在令 S(n) = T(n)/n,则S(1) = O(1),然后利用表达式带入得到S(n) = S(n/2) + O(1)

所以可以得到:S(n) = S(n/2) + O(1) = S(n/4) + O(2) = S(n/8) + O(3) = S(n/2^k) + O(k) = S(1) + O(logn) = O(logn)

综上可得,T(n) = n * log(n) = nlogn

关于归并排序的稳定性,在进行合并过程,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也不会交换,由此可见归并排序是稳定的排序算法

三、应用场景

在外排序中通常使用排序-归并的策略,外排序是指处理超过内存限度的数据的排序算法,通常将中间结果放在读写较慢的外存储器,如下分成两个阶段:

  • 排序阶段:读入能够放进内存中的数据量,将其排序输出到临时文件,一次进行,将带排序数据组织为多个有序的临时文件
  • 归并阶段:将这些临时文件组合为大的有序文件

例如,使用100m内存对900m的数据进行排序,过程如下:

  • 读入100m数据内存,用常规方式排序
  • 将排序后的数据写入磁盘
  • 重复前两个步骤,得到9个100m的临时文件
  • 将100m的内存划分为10份,将9份为输入缓冲区,第10份为输出缓冲区
  • 进行九路归并排序,将结果输出到缓冲区
    • 若输出缓冲区满,将数据写到目标文件,清空缓冲区
    • 若缓冲区空,读入相应文件的下一份数据

参考文献

  • https://baike.baidu.com/item/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F/1639015
  • https://chowdera.com/2021/09/20210920201630258d.html#_127
  • https://juejin.cn/post/6844904007899561998

深圳SEO优化公司西乡建设网站塘坑网站关键词优化荷坳如何制作网站沙井网站推广工具沙井建设网站盐田网络营销沙井网站推广方案沙井标王盐田seo排名观澜网站改版同乐网站推广爱联百度竞价包年推广西乡百度网站优化排名坪地网站搭建南澳百姓网标王推广深圳模板网站建设同乐百度网站优化排名宝安网站设计丹竹头网站推广民治营销网站西乡企业网站设计西乡网站搭建南山外贸网站建设西乡网站制作大芬网页制作丹竹头百姓网标王石岩关键词按天扣费罗湖网站优化推广塘坑网站优化推广福田网站设计歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化