代码改变世界

算法导论-线性时间排序习题解

2012-03-01 12:42  meteorgan  阅读(1284)  评论(2编辑  收藏  举报

8.1-3 证明:对于长度为n的n!中输入中至少一半而言,不存在线性时间的比较排序算法。对于n!中的1/n部分而言又怎样呢?1/2n部分呢?

  解:即在决策树模型中求1/2, 1/n, 1/2n 部分的平均路径长度。分别为 \lg\frac{n!}{2}, \lg\frac{n!}{n}, \lg\frac{n!}{2^{n}}。渐近时间复杂度均为O(nlgn)。

 

  8.3-4 说明如何在O(n)时间内,对0到n2-1之间的n个整数进行排序。

  解: 这个问题技巧性较强。基数排序,以n为基数,数长度为2,每位有n个可能取值。时间复杂度O(n)。

 

 8.3-5 在本节的第一个卡片排序算法中,为排序d位十进制数,在最坏情况下需要排序几遍?最坏情况下操作员要看管几堆卡片?

  解:第一个卡片排序算法,即从高位开始进行基数排序。用这种方法进行排序,第一遍情况下把所有数分为10组,然后需要对每组数据的第二位进行一遍排序,最坏情况下每组数据又分为10组。

    这样当前组每排序一遍就分为10组数据。第一位排序1遍,第二位10遍,第i位10i-1 遍,最坏情况下需排序(10d - 1)/9 遍。在第d位共有10d  堆。

 

 8.4-4 在单位圆中有n各点,p_{i} = (x_{i}, y_{i}),使得 0 < {x_{i}}^{2} + {y_{i}}^2 \le 1, i = 1, 2, \dots, n。假设所有点都是均匀分布的,亦即,某点落在某一区域中的概率与该区域的面积成正比。请设计一个 \Theta(n) 期望时间的算法,来根据点到原点的距离 d_{i} = \sqrt{{x_{i}}^{2} + {y_{i}}^{2}} 对n个点排序。

  解:桶排序: 点均匀分布,则每个桶的尺寸应相等,即每个桶在圆中所占据的面积相等。把圆分为n个部分,第一个部分是以原点为圆心的圆,其他部分是以原点为圆心的圆环。设第i部分的半径为

ri (外圆环到原点距离),则对于相邻的i,j。i < j,有 rj - ri = 1/n,又r1 = 1/n。据此可求可ri ,可得各圆环的半径。


 8.4-5 一个随机变量X的的概率分布函数P(x)定义为P(x) = Pr{X <= x}。假设n个随机变量X1,X2, ...,Xn 符合连续概率分布函数P, 它在O(1)时间内计算。说明如何在线性时间期望内排序这n个数。

  解:X符合分布P,不一定是均匀分布,且不知范围。但P(x)值属于[0, 1],且对于X严格单调递增,排序P(x)即排序X。将P(x)均匀分为n个部分,由于X随机选取,所以落入每个范围的概率相同。

如果 (i-1)/n <= p(xi) < i/n,则将它放入第i个桶中。


8-2 以线性时间排序

  解: a) b) c) 可用同一算法解决:用两个指针i, j。i -> 0, j -> 1。从右往左扫描数组,如果 j > i 则交换j, i 所指的元素,否则移动指针。

    d) 算法同a)中算法,在比较两元素大小的时候可以用基数排序,a)中算法比较次数不超过n。两个元素基数排序时间为O(d)。时间复杂度为O(dn)。

    e) 还是上代码吧:

 

 1 void inplace_counting_sort(int *arr, int size, int k)
2 {
3 int *temp = (int*)malloc(sizeof(int)*k);
4 int *temp1 = (int*)malloc(sizeof(int)*k);
5 int *temp2 = (int*)malloc(sizeof(int)*k);
6 int i;
7 for(i = 0; i < k; i++)
8 {
9 temp[i] = 0;
10 temp1[i] = 0;
11 temp2[i] = 0;
12 }
13 for(i = 0; i < size; i++)
14 {
15 temp[arr[i]] += 1;
16 temp1[arr[i]] += 1;
17 temp2[arr[i]] += 1;
18 }
19 for(i = 1; i < k; i++)
20 {
21 temp[i] += temp[i-1];
22 temp1[i] += temp1[i-1];
23 }
24
25 // from size-1 to 0, make sure every element is in its right postion.
26 int j = size - 1;
27 while(j >= 0)
28 {
29 int value = arr[j];
30 // if value in its rightpostion,skip this position; otherwise swap the values in
31 // arr[j] and arr[temp[value]]
32 if((j >= temp1[value]-temp2[value])&&(j <= temp1[value]-1))
33 {
34 if(temp[value] == j+1)
35 temp[value]--;
36 j--;
37 }
38 else
39 {
40 arr[j] = arr[temp[value]-1];
41 arr[temp[value]-1] = value;
42 temp[value]--;
43 }
44 }
45
46 free(temp);
47 free(temp1);
48 free(temp2);
49 }




  8-4 水壶

  解:a) 略

    b) 两种水壶共有n!中对应,决策树模型中节点个数不少于n!。比较次数最少为lgn!。

         c) 类似快速排序:

     1. 从红色水壶中随机挑选一个水壶r,找到对应的蓝色水壶b,并将蓝色水壶分为容量大于r和小于r的两部分r>, r<。

       2. 用b将红色水壶分为容量大于b和小于b的两部分b>, b<。

     3. 利用上述方法分别比较r>, b> 和 r<, b<。