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 )
    python学习笔记:算法之归并排序(merge sort)_第1张图片

二、算法效率

时间复杂度:用大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)=2T(n/2)+n

  • T ( n / 2 ) T(n/2) T(n/2):将列表L拆分为2个长度为n/2的子列表进行归并排序,每个子列表归并用时为T(n/2);
  • n 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} T(n)T(2n)T(22n)......T(2k1n)=2T(2n)+n=2T(22n)+n/2=2T(23n)+n/22=2T(2kn)+2k1n(1)
    将上述一组等式依次由下往上带入计算可得:
    (2) T ( n ) = 2 k ∗ T ( n 2 k ) + k ∗ n T(n)=2^k*T(\frac{n}{2^k})+k*n\tag{2} T(n)=2kT(2kn)+kn(2)
    n = 2 k n=2^k n=2k,则等式(2)为:
    (3) T ( n ) = n ∗ T ( 1 ) + n ∗ l o g 2 n T(n)=n*T(1)+n*log_2n\tag{3} T(n)=nT(1)+nlog2n(3)
    这里, T ( 1 ) = 1 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)=n+nlog2n(4)
    显然, T ( n ) = O ( n l o g n ) T(n)=O(nlogn) T(n)=O(nlogn)(常简记 l o g 2 n log_2n log2n l o g n logn logn),即: 输入每增大10倍,算法所需时间提高1倍。

三、python实现

你可能感兴趣的:(python学习笔记:算法之归并排序(merge sort))