基础知识
算法分析
我们先来求解一个排序问题:
输入: n n n个数的一个序列 ⟨ a 1 , a 2 , ⋯   , a n ⟩ \langle a_1,a_2,\cdots,a_n\rangle ⟨a1,a2,⋯,an⟩。
输出: 输入序列的一个排列 ⟨ a 1 ′ , a 2 ′ , ⋯   , a n ′ ⟩ \langle a_1',a_2',\cdots,a_n'\rangle ⟨a1′,a2′,⋯,an′⟩,满足 a 1 ′ ≤ a 2 ′ ≤ ⋯ a n ′ a_1'\leq a_2'\leq \cdots a_n' a1′≤a2′≤⋯an′。
插入排序的算法伪代码如下:
for j = 2 j=2 j=2 to j j j. l e n g t h length length
- k e y = A key=A key=A[ j j j]
- // Insert A A A[ j j j] into the sorted sequence A A A[ 1.. j − 1 1..j-1 1..j−1]
- i = j − 1 i=j-1 i=j−1
- while i > 0 i>0 i>0 and A A A[ i i i] > k e y >key >key
- A [ i + 1 ] = A [ i ] A[i+1]=A[i] A[i+1]=A[i]
- i = i − 1 i=i-1 i=i−1
- A [ i + 1 ] = k e y A[i+1]=key A[i+1]=key
为分析这个算法的时间代价,我们假定第 i i i行所需的时间代价为 c i c_i ci。我们首先给出这个过程中每条语句的执行时间和执行次数。其中, t j t_j tj表示对于特定的 j j j执行while循环的次数。
伪代码 | 代价 | 次数 |
---|---|---|
for j = 2 j=2 j=2 to j j j. l e n g t h length length | c 1 c_1 c1 | n n n |
k e y = A key=A key=A[ j j j] | c 2 c_2 c2 | n − 1 n-1 n−1 |
// Insert A A A[ j j j] into the sorted sequence A A A[ 1.. j − 1 1..j-1 1..j−1] | 0 0 0 | n − 1 n-1 n−1 |
i = j − 1 i=j-1 i=j−1 | c 4 c_4 c4 | n − 1 n-1 n−1 |
while i > 0 i>0 i>0 and A A A[i] > k e y >key >key | c 5 c_5 c5 | ∑ j = 2 n t j \sum_{j=2}^n t_j ∑j=2ntj |
A [ i + 1 ] = A [ i ] A[i+1]=A[i] A[i+1]=A[i] | c 6 c_6 c6 | ∑ j = 2 n ( t j − 1 ) \sum_{j=2}^n (t_j-1) ∑j=2n(tj−1) |
i = i − 1 i=i-1 i=i−1 | c 7 c_7 c7 | ∑ j = 2 n ( t j − 1 ) \sum_{j=2}^n (t_j-1) ∑j=2n(tj−1) |
A [ i + 1 ] = k e y A[i+1]=key A[i+1]=key | c 8 c_8 c8 | n − 1 n-1 n−1 |
总运行时间 T ( n ) T(n) T(n)为代价与次数之积求和,得:
T ( n ) = c 1 n + c 2 ( n − 1 ) + c 4 ( n − 1 ) + c 5 ∑ j = 2 n t j + c 6 ∑ j = 2 n ( t j − 1 ) + c 7 ∑ j = 2 n ( t j − 1 ) + c 8 ( n − 1 ) T(n)=c_1 n+c_2 (n-1)+c_4 (n-1)+c_5 \sum_{j=2}^n t_j +c_6\sum_{j=2}^n (t_j-1)+c_7\sum_{j=2}^n (t_j-1)+c_8(n-1) T(n)=c1n+c2(n−1)+c4(n−1)+c5j=2∑ntj+c6j=2∑n(tj−1)+c7j=2∑n(tj−1)+c8(n−1)
当输入的数组已排好序时,则出现最佳情况,此时 t j = 1 t_j=1 tj=1。从而
T ( n ) = c 1 n + c 2 ( n − 1 ) + c 4 ( n − 1 ) + c 5 ( n − 1 ) + c 8 ( n − 1 ) = ( c 1 + c 2 + c 4 + c 5 + c 8 ) n − ( c 2 + c 4 + c 5 + c 8 ) \begin{aligned} T(n) & = c_1 n+c_2(n-1)+c_4(n-1)+c_5(n-1)+c_8(n-1)\\ & = (c_1+c_2+c_4+c_5+c_8)n-(c_2+c_4+c_5+c_8) \end{aligned} T(n)=c1n+c2(n−1)+c4(n−1)+c5(n−1)+c8(n−1)=(c1+c2+c4+c5+c8)n−(c2+c4+c5+c8)
可将该运行时间表示为 a n + b an+b an+b,因此,它是 n n n的线性函数。
当输入的数组已反向排序时,则出现最坏情况。此时, t j = j t_j=j tj=j。利用以下公式:
∑ j = 2 n j = n ( n + 1 ) 2 − 1 ∑ j = 2 n ( j − 1 ) = n ( n − 1 ) 2 \sum_{j=2}^n j=\frac{n(n+1)}{2}-1\\ \sum_{j=2}^n (j-1)=\frac{n(n-1)}{2} j=2∑nj=2n(n+1)−1j=2∑n(j−1)=2n(n−1)
可得
T ( n ) = c 1 n + c 2 ( n − 1 ) + c 4 ( n − 1 ) + c 5 ( n ( n + 1 ) 2 − 1 ) + c 6 ( n ( n − 1 ) 2 ) + c 7 ( n ( n − 1 ) 2 ) + c 8 ( n − 1 ) = ( c 5 + c 6 + c 7 2 ) n 2 + ( c 1 + c 2 + c 4 + c 5