美文网首页
合并排序&分治法

合并排序&分治法

作者: 山高月更阔 | 来源:发表于2020-08-05 08:50 被阅读0次

    分治法三个步骤

    分解:将原问题分解成一系列子问题;
    解决:递归解决各个子问题,若子问题足够小,则直接求解子问题;
    合并:将子问题的结果合并成原问题的解;

    合并排序完全按照了上述模式
    分解:将 n 个元素分成含 n / 2 个元素的子序列;
    解决:用合并排序法对两个子序列递归排序;
    合并:将两个子序列合并以得到已排序的结果;

    合并排序过程

    如图所示:


    image.png

    合并排序代码

    func MergeSort(data []int, p int, r int) {
        if p >= r {
            return
        }
        q := p + (r-p)/2
        MergeSort(data, p, q)
        MergeSort(data, q+1, r)
        merge(data, p, q, r)
    }
    
    func merge(data []int, p int, q int, r int) {
        L := make([]int, q-p+1)
        for i := p; i <= q; i++ {
            L[i-p] = data[i]
        }
        L = append(L, math.MaxInt32)  //为了不实时排到是否最后一个数字 添加一个哨兵
        R := make([]int, r-q)
        for i := q + 1; i <= r; i++ {
            R[i-q-1] = data[i]
        }
        R = append(R, math.MaxInt32)  //添加哨兵
        i, j := 0, 0
        for k := p; k <= r; k++ {
            if L[i] < R[j] {
                data[k] = L[i]
                i++
            } else {
                data[k] = R[j]
                j++
            }
        }
    }
    
    

    分治法算法分析

    T(n) = O(1) 当n = 1
    T(n) = aT(n/b) + D(n) +C(n) 当n>2
    当n = 1时 只有一个元素 显然 T(n) = O(1)
    当n>1时 D(n)表示分解问题 C(n) 表示合并问题

    合并排序算法分析

    假设不考虑n = 1的特征情况,O(1) < O(n) 其实也包含在T(n中)
    在合并算法中 a = b = 2,分解与合并问题统一为cn
    所以 T(n) = 2T(n/2)+cn

    由于每次分解为1/2 假设一个2^n个元素分解情况如下:


    image.png

    由于每层时上层的1/2, 从cn到cn/2...c 高度应该是lgn。每次需要的时间为cn
    所以 T(n) = cnlgn+cn
    所以合并排序时间复杂度为 O(nlgn)

    回顾分治法过程

    分解:将原问题分解成一系列子问题;
    解决:递归解决各个子问题,若子问题足够小,则直接求解子问题;
    合并:将子问题的结果合并成原问题的解;
    分治法时求解复杂问题的一种很好思路。

    相关文章

      网友评论

          本文标题:合并排序&分治法

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