美文网首页数据结构
内排序7:二路归并排序

内排序7:二路归并排序

作者: 玲儿珑 | 来源:发表于2021-03-21 22:26 被阅读0次

归并是指将两个或多个按值有序序列合并成为一个按值有序序列的过程。
二路归并是将两个按值有序序列合并成为一个按值有序序列。
同理,有 三路归并,思路归并等。

归并子算法:
功能是把位置相邻的两个按值有序的序列合并为一个按值有序的序列
具体实现如下:

var merge = function(X, Z, s, u, v) {
    //将有序的x[s..u]和x[u+1..v]归并为有序的x[s..v]
    let i, j, q
    i = s
    j = u + 1
    q = s

    while (i <= u && j <= v) {
        if (X[i] < X[j]) {
            Z[q++] = X[i++]
        } else {
            Z[q++] = X[j++]
        }
    }

    while (i <= u) {
        Z[q++] = X[i++]
    }
    while (j <= v) {
        Z[q++] = X[j++]
    }
}

一趟归并扫描子算法:
功能是将参加排序的序列分成若干长度为t的,且各自按值有序的子序列,然后多次调用归并子算法Merge将所有两两相邻成对的子序列合并成若干个长度为2t的、且各自按值有序的子序列。
具体实现如下:

var mpass = function(X, Y, n, t) {
    let i = 0;
    while (n - i + 1 > 2 * t) {
        merge(X, Y, i, i + t - 1, i + 2 * t - 1)
        i = i + 2 * t
    }
    if (n - i + 1 > t) {
        merge(X, Y, i, i + t - 1, n - 1)
    } else {
        for (let j = i; j < n; j++) {
            Y[j] = X[j]
        }
    }
}

二路归并排序:
就是最初将长度为n的原始序列理解为由n个长度为1的按值有序的子序列组成,并把这些子序列中相邻的子序列两两成对地进行合并,得到[n/2]个长度为2的按值有序子序列(若n为奇数,则还有第[n/2]个子序列,它是原序列中最后那个子序列);然后将这些子序列又两两成对地进行合并,得到[n/4]个长度为4的按值有序子序列;依次类推,最后只剩一个长度为n的子序列,这个子序列就是原始序列经过二路归并排序后的结果。
具体实现如下:

var mergeSort = function(X) {
    let t = 1
    let n = X.length
    let Y = []
    let isx = false
    while (t < n) {
        mpass(X, Y, n, t)
        isx = false
        t *= 2
        if (t <= n) {
            mpass(Y, X, n, t)
            isx = true
        }
        t *= 2
    }
    return isx? X:Y
}
var arr = [5, 3, 8, 1, 9, 2, 7, 4, 6, 10]
console.log(mergeSort(arr))

时间复杂度为O(nlog2n)
空间复杂度为O(n)
是稳定排序

第二种方法:

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

function merge(left, right)
{
    var 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;
}
var arr = [5,3,8,1,9,2,7,4,6,10]
mergeSort(arr)

相关文章

  • 排序算法之归并排序

    1、归并排序的基本思想 归并排序主要是二路归并排序。二路归并排序的基本思想,设数组a中存放了n个数据元素,初始时把...

  • 常见算法前端JS实现 — 排序

    1.排序算法 1.1 冒泡排序 1.2 快速排序 1.3 二路归并

  • 归并排序+基数排序

    归并排序 二路归并排序归并过程 O(n)整个归并排序需要⌈log2n⌉趟(k路归并需要⌈logkn⌉) 空间效率O...

  • 内排序7:二路归并排序

    归并是指将两个或多个按值有序序列合并成为一个按值有序序列的过程。二路归并是将两个按值有序序列合并成为一个按值有序序...

  • 前端常见算法

    冒泡排序 快速排序 二路归并将两个按值有序序列合并成一个按值有序序列,则称之为二路归并排序 判断回文字符串 翻转字...

  • 面试知识点

    排序冒泡排序快速排序选择排序插入排序二路归并 查找二分查找 排序和查找的java实现 java语言Java字符串字...

  • 外排序-多路归并

    内排序的归并排序是采用二路归并。 将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有...

  • 算法复习-归并类排序(1)-二路归并排序

    二路归并排序 归并排序可以看作一个分而治之的过程:先将整个序列分成两半,对每一半分别进行归并排序,将得到两个有序序...

  • 排序算法 希尔、归并排序

    希尔排序与归并排序都是分组进行比较,但是希尔排序是组间比较,归并排序是组内排序 希尔排序 设置一个增量gap,从第...

  • 【数据结构】【C#】021-归并类排序: ✌二路归并(稳定)

    归并排序:二路归并(稳定) 基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即...

网友评论

    本文标题:内排序7:二路归并排序

    本文链接:https://www.haomeiwen.com/subject/jzzgcltx.html