归并排序

2017/7/5 posted in  算法&数据结构

导论第二章再讲时间复杂度的计算,通过写插入排序( 插入排序与循环不变式 )讲了循环的时间复杂度的计算,而接着通过归并排序介绍分治法以及分治法的时间复杂度。

A = [2, 5, 1, 3, 7, 6]

def merge_sort(nums, start, end):
    if end <= start + 1:
        return nums
    m = (start + end ) / 2
    merge_sort(nums, start, m)
    merge_sort(nums, m, end) # not m + 1

    l_nums = nums[start:m]
    r_nums = nums[m:end]
    l_nums_len = len(l_nums)
    r_nums_len = len(r_nums)
    s = j = 0
    for i in range(start, end):
        if s < l_nums_len and j < r_nums_len:
            if l_nums[s] < r_nums[j]:
                nums[i] = l_nums[s]
                s += 1
            else:
                nums[i] = r_nums[j]
                j += 1
        else:
            break

    while i < end:
        if s < l_nums_len:
            nums[i] = l_nums[s]
            s += 1
        if j < r_nums_len:
            nums[i] = r_nums[j]
            j += 1
        i += 1

    return nums

我实现的代码可能不是很 pythonic,甚至也和导论中给出的伪代码有些区别。

在这里踩得坑是注释的地方,在我执行完 merge_sort(nums, start, m) 之后,想当然的执行了 merge_sort(nums, m + 1, end),其实这是不对的,因为这里的区间是 [start, end),如果在运行左边部分的时候,使用 m + 1,那么在 m 那个位置上的值将被忽略掉。