算法導論第三版第七章課後答案

7.1-1 參照圖7-1的方法,說明PARTITION在數組A={13,9,9,5,12,8,7,4,21,2,6,11}上的操作過程。

A={13,19,9,5,12,8,7,4,21,2,6,11}

  ={13,19,9,5,12,8,7,4,21,2,6,11}

  ={13,19,9,5,12,8,7,4,21,2,6,11}

  ={9,19,13,5,12,8,7,4,21,2,6,11}

  ={9,5,13,19,12,8,7,4,21,2,6,11}

  ={9,5,13,19,12,8,7,4,21,2,6,11}

  ={9,5,8,19,12,13,7,4,21,2,6,11}

  ={9,5,8,7,12,13,19,4,21,2,6,11}

  ={9,5,8,7,4,13,19,12,21,2,6,11}

  ={9,5,8,7,4,13,19,12,21,2,6,11}

  ={9,5,8,7,4,2,19,12,21,13,6,11}

  ={9,5,8,7,4,2,6,12,21,13,19,11}

  ={9,5,8,7,4,2,6,11,21,13,19,12}

7.1-2 當數組A[p..r]中的元素都相同時,PARTITION返回的q值是什麼?修改PARTITION,使得當數組A[p..r]中所有元素的值都相同時,q=(p+r)/2.

當元素相同時,q=i+1=r-1+1=r.

修改後的函數q=(p+r)/2.

[cpp] view plain copy
  1. int Partition(int A[], int p, int r)  
  2. {  
  3.    int x = A[r],i=p-1;  
  4.    int flag = 1;  
  5.    for (int j = p;j< r-1;j++)  
  6.    {  
  7.        if (x >=A[i]&&flag>0)//x=A[i]時,flag大於0和小於0的數量約爲一半,  
  8.        {  
  9.            i = i + 1;  
  10.            swap(A[i],A[j]);  
  11.        }  
  12.        if (x ==A[i])  
  13.        {  
  14.            flag=-flag;//這樣就能讓i++次數減半。  
  15.        }  
  16.    }  
  17.     swap(A[i + 1],A[r]);  
  18.    return i + 1  
  19. }  

7.1-3請簡要證明:在規模爲n的子數組上,PARTITION的時間複雜度爲Θ(n)


除了函數內數個O(1),還有一個循環,其循環次數 p-(r-1)+1=p-r次,O(p-r)=O(n)


7.1-4  如何修改QUICKSORT,使得它能夠以非遞增序進行排序?

僅僅需要把  x >=A[i] 改爲 x <=A[i]

7.2-1 利用帶入法證明:正如7.2節開頭提到的那樣,遞歸式T(n)=T(n-1)+Θ(n)的解爲T(n)=Θ(n^2)  令Θ(n)=cn (c常數)。

 假設T(n)在n-1上成立。  先證明T(n)=Ο(n^2)

T(n)<=c1(n-1)^2+cn<=c1n^2 <=> (c-2c1)n+c1<=0 <=> c-2c1<0 (c<2c1) n>=c1/(2c1-c) 當0<c<2c1時,有n>=n0=c1/(2c1-c)  對於足夠大的n都成立。

再證明T(n)=Ω(n^2)  T(n)>=c2(n-1)^2+cn>=c2n^2  <=> (c-2c2)n+c2>=0 <=> c-2c2>0 (c>2c2>0) n>0 當c>2c2>0時,有n>0,對於足夠大的n都成立。

 所以存在常數c1>c/2,c2<c/2時,存在n0=max{c1/(2c1-c),0},使得當n>=n0時,對於足夠大的n都成立,T(n)=Θ(n^2)成立 

 7.2-2當數組A的所有元素都具有相同值時,QUICKSORT的時間複雜度是什麼?  

 當數組A所有元素相同時,QUICKSORT中的劃分時極爲不平衡的,n-1:0的劃分,T(n)=T(n-1)+Θ(n)解這個遞歸式T(n)=Θ(n^2) 

 7.2-3 證明:當數組A包含的元素不同,並且是按降序排列的時候,QUICKSORT的時間複雜度爲Θ(n^2)

 按照降序排序時,在QUICKSORT中的劃分時極爲不平衡的,n-1:0的劃分,所以其時間複雜度爲T(n)=T(n-1)+Θ(n)解這個遞歸式  T(n)=T(n)=Θ(n^2)

 7.2-4 銀行一半會按照交易時間來記錄某一賬戶的交易情況。但是,很多人卻喜歡收到銀行對賬單是按照支票號碼的順序來排列的。這是因爲,人們通常  都是按照支票號碼的順序來開出支票的,而商人也通常都是根據支票編號的順序兌付支票。這一問題時按照交易時間排序的序列轉換成按支票號排序的  序列,它是指上是一個對幾乎有序的輸入序列進行排序的問題。請證明:在這個問題上,INSERTION-SORT的性能往往要優於QUICKSORT?

插入排序在基本有序的情況下,基本無需移動任何元素來插入,所以只有外層循環了n次,所以時間複雜度爲O(n)

 快速排序在基本有序的情況下,在劃分數組時,劃分得非常不平衡,那麼其時間複雜度是O(nlgn),而達到完全有序時,時間 複雜度達到O(n^2),</p><p>所以總之插入排序要優於快速排序。 

7.2-5 假設快速排序的每一層所做的劃分的比例都是1-a:a,其中0<a<=1/2且是一個常數。是證明,在相應的遞歸樹中,葉結點的最小深度大約是  -lgn/lga,最大深度大約是-lgn/lg(1-a)(無需考慮整數舍入問題) 

 0<=a<=1/2  =>  a<1-a 只有T(1)時,到達樹底,設樹高度爲k,所以就有  最小深度(a^k)n=1=>k=-lgn/lga 最大深度(1-a)^kn=1 => k=-lgn/lg(1-a)

 7.2-6試證明:在一個隨機輸入數組上,對於任何常數0<a<=1/2,PARTITION產生比1-a:a更平衡的劃分的概率約爲1-2a      

 設隨機數組有n個數,則有A0,A1...Aan...A(1-a)n...An。</p><p>設X個數被劃分在左半部分,Y個數被劃分在右半部分。

則X+Y=n  那麼根據書上根據平衡的定義,X-Y差值越大,比例就越高,那麼越不平衡,只有X-Y差值越小,越接近0,X約等於Y的時候  越平衡。

 分三種情況討論:1)當X<a時,那麼Y>1-a, |X-Y|>1-2a>0               

                              2)當X>1-a時,那麼Y<a, |X-Y|>1-2a>0         

                              3)當a<X<1-a時,那麼a<Y<1-a,0<|X-Y|<1-2a

 只有當|X-Y|距離小於一個數時,纔可能X-Y差值趨向於0,劃分的就越平衡。所以我們選擇情況3的這種劃分。  在an與(1-a)n之間取X的值,因爲劃分X落在區間[0,n]上是等可能性的,所以符合均勻分佈,落在[an,(1-a)n}]上的任意一點  的概率也是等可能的,所以P{an≤x≤(1-a)n}=((1-a)n-an)/(n-0)=1-2a。得證! 

7.3-1 爲什麼我們分析隨機化算法的期望運行時間,而不是其最壞運行時間呢?

 隨機化算法不能改變最壞情況下得運行時間,但是能降低最壞情況發生的概率。

  7.3-2在RANDOMIZED-QUICKSORT的運行過程中,在最壞情況下,隨機數生成器RANDOM被調用了多少次?在最好情況下呢? 

最好情況是均勻劃分,其時間複雜度 T(n)=2T(n/2)+1 =>主定理case1得T(n)=Θ(n)   

最壞情況是分成不平衡的劃分,其時間複雜度 T(n)=T(n-1)+T(0)+1 各式相加得=>T(n)=Θ(n)  

7.4-2 證明:在最好的情況下,快速排序的運行時間爲Ω(nlgn)

最好情況就是均分的情況下,T(n)=2T(n/2)+Θ(n) 滿足主定理case2=>T(n)=Θ(nlgn)=Ω(nlgn)

7.4-4 證明:RANDOMIZED-QUICKSORT期望運行時間是Ω(nlgn).

根據書中7.4.2知:隨機化快速排序和普通快速排序就是主元選擇上有所不同,其他都相同。所以我們可以用分析普通快排的方法分析隨機快排,普通快排最好的情況是均分,其時間複雜度Ω(nlgn).,那麼快速排序的時間複雜度至少最好情況下的Ω(nlgn)。所以隨機化快排也是Ω(nlgn)。

7.4-5 當輸入數據已經集合有序時,插入排序速度很快。在實際應用中,我們可以利用這一特點來提高快速排序的速度。當對一個長度小於k的子數組

調用快速排序時,讓它不做任何排序就返回。當上層的快速排序調用返回後,對整個數組運行插入排序來完成排序過程。試證明,這一排序算法的期望

時間複雜度爲O(nk+nlg(n/k)).分別從理論和實踐的角度說明我們應該如何選擇k?


7.4-5的具體程序實現如下:

[cpp] view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3. int PARTITION(int A[],int p,int r)  
  4. {  
  5.     int x=A[r];  
  6.     int i=p-1;  
  7.     for (int j=p;j<=r-1;j++)//O(n)這裏應該包含第r-1個元素在循環裏  
  8.     {  
  9.         if (A[j]<=x)  
  10.         {  
  11.             i++;  
  12.             swap(A[i],A[j]);  
  13.         }  
  14.     }  
  15.     swap(A[i+1],A[r]);  
  16.     return i+1;  
  17. }  
  18. void QUICKSORT(int A[],int p,int r,int k)  
  19. {  
  20.     if (p<r&&r-p>=k)//T(n)=2  
  21.     {  
  22.         int q=PARTITION(A,p,r);  
  23.         QUICKSORT(A,p,q-1,k);  
  24.         QUICKSORT(A,q+1,r,k);  
  25.     }  
  26. }  
  27. void INSERTION_SORT(int A[],int r)  
  28. {  
  29.     int key;  
  30.     for (int j=1;j<=r;j++)  
  31.     {  
  32.         key=A[j-1];  
  33.         int i=j-1;  
  34.         while (i>0&&A[i-1]<key)//a)插入排序時間複雜度O(n^2)對於長度爲k的子列表都有O(k^2),則n/k個爲(k^2)*n/k=O(nk)  
  35.         {  
  36.             A[i]=A[i-1];  
  37.             i=i-1;  
  38.         }  
  39.         A[i]=key;  
  40.     }  
  41. }  
  42. void main()  
  43. {  
  44.     int A[16]={1,5,10,8,9,4,6,2,7,3,14,20,35,48,25,34};  
  45.     QUICKSORT(A,0,15,4);//K=3  
  46.     for (int i=0;i<16;i++)  
  47.     {  
  48.         cout<<A[i]<<" ";  
  49.     }  
  50.     cout<<endl;  
  51.     INSERTION_SORT(A,16);  
  52.     for ( i=0;i<16;i++)  
  53.     {  
  54.         cout<<A[i]<<" ";  
  55.     }  
  56. }  

7.4-6 考慮對PARTITION過程做這樣的修改,從數組A中隨機選出三個元素,並用這三個元素的中位數(既這三個元素按大小排在中間的值)對數組進行

劃分。求以a的函數形式表示的,最壞劃分比例爲a:(1-a)的近似概率,其中 0<a<1.

題目上說最壞劃分比例是a:(1-a),那麼由書中分析知 最壞劃分比例是0:(n-1)或是(n-1):0 這纔是最壞劃分比例,所以
據我分析,題意應該是比a:(1-a)更壞的劃分比例。還有就是因爲是隨機選取的3個元素並從中取中位數,那麼從0到n-1上的每個
元素都可以做主元,所以取出的中位數是等可能的,符合均勻分佈條件。
      設x爲數組前半部分的元素個數,y爲數組後半部分的元素個數。
當1<a<1/2時,a<1-a p(x<a)+p(x>1-a)+p(a<x<a-1)=1看7.2-6題已經給出答案。 x<a或者x>1-a時,劃分情況比a:(1-a)更壞,
更糟糕的概率是p(x<a∪x>1-a)=p(x<a)+p(x>1-a)=1-p(a<x<1-a)=1-(1-2a)=2a
同上可知,當1/2<a<1時,a>1-a p(x>a)+p(x<1-a)+p(a<x<1-a)=1 ,x>a或者x<1-a時,劃分情況比a:(1-a)更壞,更糟糕的概率
是p(x<1-a∪x>a)=p(x>a)+p(x<1-a)=1-p(a<x<1-a)=1-(2a-1)=2-2a

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章