您的位置:首页 > 其它

CLRS 7.4快速排序分析

2015-10-14 08:58 369 查看
7.4-1

T(n)=max0≤q≤n−1(T(q)+T(n−q−1))+Θ(n)≥T(0)+T(n−1)+Θ(n)=Θ(n2) \begin{align}
T(n) &= \max_{0 \le q \le n-1} (T(q) + T(n-q-1)) + \Theta(n) \\
&\ge T(0)+T(n-1) + \Theta(n) \\
&=\Theta(n^2)
\end{align}

所以 T(n)=Ω(n2)T(n)=\Omega(n^2)。

7.4-2

最好情况下 T(n)=2T(n/2)+Θ(n)T(n)=2T(n/2)+\Theta(n),运用主方法得 T(n)=Θ(nlgn)T(n)=\Theta(n\lg n)。

7.4-3

f(q)f′(q)f′′(q)=q2+(n−q−1)2=2q−2(n−q−1)=4q−2n+2=4 \begin{align}
f(q) &= q^2 + (n - q - 1)^2 \\
f'(q) &= 2q - 2(n - q - 1) = 4q - 2n + 2 \\
f''(q) &= 4 \\
\end{align}

令 f′(q)=0f'(q) = 0 有 q=12n−12q = \frac{1}{2}n - \frac{1}{2}。由于 f′′(q)=4>0 f''(q) = 4>0,所以 f′(q)f'(q) 单调递增,也就是说当 q<12n−12q <\frac{1}{2}n - \frac{1}{2} 时 f′(q)<=0f'(q)<=0,当 q>12n−12q>\frac{1}{2}n - \frac{1}{2}时f′(q)>=0f'(q)>=0,即 f(q)f(q) 在 00~(12n−12)(\frac{1}{2}n - \frac{1}{2}) 单调递减,在 (12n−12)(\frac{1}{2}n - \frac{1}{2})~nn 单调递增,通过验证有 q=0q=0 或者 q=n−1q=n-1 时使得 f(q)f(q) 取得最大值。

7.4-4

类似于书上的期望运行时间。

E[X]=∑i=1n−1∑j=i+1n2j−i+1=∑i=1n−1∑k=1n−i2k+1≥∑i=1n−1∑k=1n−i22k≥∑i=1n−1Ω(lgn)=Ω(nlgn)(k≥1) \begin{align}
E[X] &= \sum_{i=1}^{n-1} \sum_{j=i+1}^n \frac{2}{j-i+1} \\
&= \sum_{i=1}^{n-1} \sum_{k=1}^{n-i} \frac{2}{k + 1} & (k \ge 1) \\
&\ge \sum_{i=1}^{n-1} \sum_{k=1}^{n-i} \frac{2}{2k} \\
&\ge \sum_{i=1}^{n-1} \Omega(\lg{n}) \\
&= \Omega(n\lg{n})
\end{align}

7.4-5

快排时,在第 lgnk\lg{\frac nk} 层时停止递归调用,花费时间 O(nlgnk)O(n\lg{\frac nk})。然后利用插入排序,时间复杂度 nkO(k2)=O(nk)\frac nkO(k^2)=O(nk)。

在理论中:

cqnlgn≥cink+cqnlg(nk)⇓cqlgn≥cik+cqlgn−cqlgk⇓lgk≥cicqk c_qn\lg{n} \ge c_ink + c_qn\lg(\frac nk) \\
\Downarrow \\
c_q\lg{n} \ge c_ik + c_q\lg{n} - c_q\lg{k} \\
\Downarrow \\
\lg{k} \ge \frac{c_i}{c_q}k

附上代码:

#include <iostream>
#include <cstdlib>
using std::cout;
using std::endl;

const int threshold = 5;  //阈值只为验证程序正确性之用,不是实际取值

void INSERT_SORT(int *array,int p,int r)
{
for(int i = p + 1; i <= r; ++i)
{
int key = *(array + i);
int j = i - 1;
while(j >= p && *(array + j) > key)
{
*(array + j + 1) = *(array + j);
--j;
}
*(array + j + 1) = key;
}
}

int PARTITION(int *array,int p,int r)
{
int pivot = *(array + r);
int i = p - 1;
for(int j = p; j < r; ++j)
{
if(*(array + j) <= pivot)
{
++i;
int temp = *(array + j);
*(array + j) = *(array + i);
*(array + i) = temp;
}
}
int temp = *(array + i + 1);
*(array + i + 1) = *(array + r);
*(array + r) = temp;
return i + 1;
}

int RANDOMIZED_PARTITION(int *array,int p,int r)
{
int i = rand() % (r - p + 1) + p;
if(i != r)
{
int temp = *(array + i);
*(array + i) = *(array + r);
*(array + r) = temp;
}
return PARTITION(array,p,r);
}

void RANDOMIZED_QUICKSORT(int *array,int p,int r)
{
if(p < r)
{
int q = RANDOMIZED_PARTITION(array,p,r);
RANDOMIZED_QUICKSORT(array,p,q-1);
RANDOMIZED_QUICKSORT(array,q+1,r);
}
}

void MIXED_RANDOMIZED_INSERT_QUICKSORT(int *array,int p,int r)
{
if(p < r)
{
if(r - p > threshold)
{
int q = RANDOMIZED_PARTITION(array,p,r);
MIXED_RANDOMIZED_INSERT_QUICKSORT(array,p,q-1);
MIXED_RANDOMIZED_INSERT_QUICKSORT(array,q+1,r);
}
else INSERT_SORT(array,p,r);
}
}

int main()
{
int ia[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
MIXED_RANDOMIZED_INSERT_QUICKSORT(ia,0,15);
for(int i = 0; i < 16; ++i)
cout << ia[i] << ' ';
cout << endl;
return 0;
}


7.4-6

即求任取 3 个数,中位数位于中间 (1−2α)n(1-2α)n 个位置的概率。

2((1−2α)n2)(αn1)+((1−2α)n2)(αn1)(αn1)(n3)\frac{2\binom{(1-2α)n}{2}\binom{αn}{1}+\binom{(1-2α)n}{2}\binom{αn}{1}\binom{αn}{1}}{\binom{n}{3}}

附上三个数取中的划分代码(其余代码见7.4-5)

int RANDOMIZED_PARTITION(int *array,int p,int r)
{
int i = rand() % (r - p + 1) + p;
int j = rand() % (r - p + 1) + p;
int k = rand() % (r - p + 1) + p;
int mid;
if(array[i] >= array[j])  //找出中位数
{
if(array[i] <= array[k])
mid = i;
else if(array[j] <= array[k])
mid = k;
else mid = j;
}
else
{
if(array[j] <= array[k])
mid = j;
else if(array[i] <= array[k])
mid = k;
else mid = i;
}
int temp = array[mid];
array[mid] = array[r];
array[r] = temp;
return PARTITION(array,p,r);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: