python学习笔记:算法之归并排序(merge sort)

归并排序由约翰·冯·诺伊曼(John Von Neumann)1945年提出,是典型的分治算法(divide conquer algoalgorithm)。

**一、算法描述

算法记为 mergesort(L):

  • divide:将无序列表L分成n个子列表( n=len(L)) ,每个子列表是有序的;

  • merge:两两归并子列表产生新的子列表,每个子列表是有序的;

  • merge repeatedly:重复步骤2,直至归并为1个列表。

    下面以L=[6,5,3,1,8,7,2,4]为例说明归并过程。(https://en.wikipedia.org/wiki/Merge_sort
    merge-sort

二、算法效率

时间复杂度:用大O记号法表示为 O(nlogn)。

大O记号法:big O notation,是用于描述函数渐进行为的数学符号,更确切地说它是用另一个(通常更简单的)函数来描述一个函数数量级的渐近上界

一般来说,我们用大O记号法表示的时间复杂度是对最坏情况的描述。

计算过程如下:

假设被排序列表长度为n,记时间频度为T(n),则根据上述算法描述可知: T ( n ) = 2 T ( n / 2 ) + n T(n) = 2 T(n/2) + n

  • T ( n / 2 ) T(n/2) :将列表L拆分为2个长度为n/2的子列表进行归并排序,每个子列表归并用时为T(n/2);
  • n n :将两个子列表进行合并为1个列表最坏情况下需执行n次(时间)。
    (1) T ( n ) = 2 T ( n 2 ) + n T ( n 2 ) = 2 T ( n 2 2 ) + n / 2 T ( n 2 2 ) = 2 T ( n 2 3 ) + n / 2 2 . . . . . . T ( n 2 k 1 ) = 2 T ( n 2 k ) + n 2 k 1 \begin{aligned} T(n) &=2*T(\frac{n}{2})+n \tag{1}\\ T(\frac{n}{2}) &=2*T(\frac{n}{2^2})+n/2\\ T(\frac{n}{2^2}) &=2*T(\frac{n}{2^3})+n/2^2\\ ......\\ T(\frac{n}{2^{k-1}})&=2*T(\frac{n}{2^k})+\frac{n}{2^{k-1}} \end{aligned}
    将上述一组等式依次由下往上带入计算可得:
    (2) T ( n ) = 2 k T ( n 2 k ) + k n T(n)=2^k*T(\frac{n}{2^k})+k*n\tag{2}
    n = 2 k n=2^k ,则等式(2)为:
    (3) T ( n ) = n T ( 1 ) + n l o g 2 n T(n)=n*T(1)+n*log_2n\tag{3}
    这里, T ( 1 ) = 1 T(1)=1 ,故有:
    (4) T ( n ) = n + n l o g 2 n T(n)=n+n*log_2n\tag{4}
    显然, T ( n ) = O ( n l o g n ) T(n)=O(nlogn) (常简记 l o g 2 n log_2n l o g n logn ),即: 输入每增大10倍,算法所需时间提高1倍。

三、python实现

猜你喜欢

转载自blog.csdn.net/xiaozhimonica/article/details/89470129