Stanford Algorithm 1.5 - 1.7 记录

Merge Sort

该课程前面几节课作为入门, 所以会介绍一些算法, 但后面会有更扎实、底层诸如复杂度分析等内容.

按讲者说法, 这种算法还是比较实际引用广泛的, 我后来稍微google了一下, 说这种算法最坏最好情况都是一样的时间复杂度.

思想很简单, 属于Divide and Conquer , 就是递归的把它二分打散, 再用O(N)的函数把它们merge起来. 下面的代码是不去重的, 即有重复数字仍然包含在内.

def merge_sorted_lists(a, b):
    res = []
    # init indices for a, b
    i = 0
    j = 0
    while i < len(a) and j < len(b):
        if a[i] < b[j]:
            res.append(a[i])
            i = i + 1
        else:
            res.append(b[j])
            j = j + 1
    if i < len(a):
        res = res + a[i:]
    else:
        res = res + b[j:]
    return res

def merge_sort(l):
    # THIS IS for exit!!!
    if len(l) <= 1:
        return l
    a = l[:int(len(l)/2)]
    b = l[int(len(l)/2):]
    left = merge_sort(a)
    right = merge_sort(b)
    return merge_sorted_lists(left, right)
    
if __name__ == '__main__':
    l = [4,5,7,9,7,5,1,0,7,-2,3,-99,6]
    print(merge_sort(l))

在度量其复杂度时, 讲者采用的是recursive tree, 其实就是笨办法, 把递归过程全部列出来, 计算每一层级需要的代价. 在第j (j=0,1,2,...,logN)层, 有2^j子问题(就是需要merge的), 每个子问题的size是(至多)需要6(N/(2^j))的代价(代码行数). 因此, 不管在哪一层, 代价都是6N, 所以最多就是6N(1+logN).

你可能感兴趣的:(Stanford Algorithm 1.5 - 1.7 记录)