1 问题
2 算法
2.1 伪代码
2.2 算法思想
2.3 手工演示
2.4 Python实现
# -*- coding: utf-8 -*-
import sysdef merge(A, p, q, r):n1 = q - p + 1n2 = r - qL = [0] * (n1 + 2)R = [0] * (n2 + 2)for i in range(1, n1+1):L[i] = A[p+i-1]for j in range(1, n2+1):R[j] = A[q+j]L[n1+1] = 65536R[n2+1] = 65536i = 1j = 1for k in range(p, r+1):if L[i] <= R[j]:A[k] = L[i]i = i + 1else:A[k] = R[j]j = j + 1def merge_sort(A, p, r):if p < r:q = (p + r) // 2merge_sort(A, p, q)merge_sort(A, q+1, r)merge(A, p, q, r)if __name__ == '__main__':input_str = sys.stdin.readline().split()A = list(map(int, input_str))A.insert(0, 'x') # 为了使数组从1开始n = len(A) - 1print('Before sort:')print(A[1:])print('After sort:')merge_sort(A, 1, n)print(A[1:])
3 算法分析
怎样解这个递归式子?书中借用“tree”这种结构做算法分析,下一节的master定理也是用“tree”来分析的,这种分析方法,贯穿了整个《算法导论》全书,是非常有艺术性和创造性的一种方法,本小节只用“tree”直观说明,严谨一些的数学细节见下一节的master定理。
关于这个tree有一些说明:
- 树的高度h=lg(n)h=lg(n)h=lg(n);
- 叶子结点个数#leaves=n\#leaves=n#leaves=n;
- 非叶子结点表示merge所花费的时间,并且每一行所花费的时间总和都是cncncn,叶子结点表示排序一个数字所花费的时间Θ(1)\Theta(1)Θ(1),最后一行排序每一个数字所花费的总时间是Θ(n)\Theta(n)Θ(n);
- 把所有的结点加起来T(n)=h∗(cn)+Θ(n)=Θ(nlgn)T(n)=h*(cn)+\Theta(n)=\Theta(nlgn)T(n)=h∗(cn)+Θ(n)=Θ(nlgn);