演算法複習-遞迴與分治策略

來源:互聯網
上載者:User

分治(divide and conquer)策略的基本思想:

  將一個規模為n的問題分解為k個規模較小的子問題,這些子問題互相獨立且與原問題相同。遞迴地解這些子問題,然後將各子問題的解合并得到原問題的解。

大致可以通過如下模式來描述:

  divide_and_conquer( P ){

      if(|P|<= n0) adhoc(P);

     divide P into smaller subinstances P1,P2,...,Pk;

    for( i = 1 ; i <= k;i++){

         yi = divide-and-conquer(Pi);

   }

   return merge(y1,y2,...yk);

}

其中|P|表示問題P的規模.(具體見王曉東的演算法設計與分析或者演算法導論中的相關內容)

以下為分之策略的典型演算法:

1.歸併排序(MergeSort)的基本思想是:將待排序元素分成大小大致相同的兩個子集合,分別對兩個子集合進行排序,最終將排好序的子集合合并成所要求的排好序的集合。

大致可以通過如下模式來描述:

void MergeSort(Type arr[],int l,int r){
                //MergeSort l...(l+r)/2,對l到(l+r)/2進行歸併排序
                MergeSort(arr,l,(l+r)/2);

                //MergeSort (l+r)/2+1 ... r,對(l+r)/2+1到r進行歸併排序
                MergeSort(arr,(l+r)/2+1,r);

                //Merger,合并已經排好序的兩個子序列,使整個序列有序。

                merge(arr,l,r);

}

具體代碼如下:最後的合并我使用的事直接插入排序。

template<class T>void MergeSort(T arr[],int l,int r){if(l < r){       //MergeSort l...(l+r)/2MergeSort(arr,l,(l+r)/2);//MergeSort (l+r)/2+1 ... rMergeSort(arr,(l+r)/2+1,r);//Merger,direct insert sortfor(int i = (l+r)/2+1 ; i <= r ; i++ ){T temp = arr[i];int j  = i-1;//有序序列元素逐漸增多,待排序列元素逐漸減少。for(j; j >= 0 ; j--){if(arr[j] > temp ){arr[j+1] = arr[j];}else{break;}}arr[j+1] = temp;}}}

但其實,在合并部分使用直接插入有可能是件極糟糕的事情,在最壞情況下,合併作業(Merge)的時間複雜度為O(n^2),例如,無序序列{6,7,8,5 ,3,1,4,2}在最後一趟歸併中形成了有序序列{5,6,7,8} 和{1,2,3,4},執行合併作業時,由於演算法是直接插入,必然是屬於最壞的情況。對於有n個元素的類似的無序序列,最壞情況下,其時間複雜度為O(n^2).

如果改變合併作業(Merge)的演算法,則可保證合併作業在O(n)內完成,肯定能猜到,它就是合并兩個有序鏈表的演算法。

====2013年3月26日更新===========================================

歸併操作過程:https://zh.wikipedia.org/wiki/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F#.E5.BD.92.E5.B9.B6.E6.93.8D.E4.BD.9C

  1. 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合并後的序列
  2. 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置
  3. 比較兩個指標所指向的元素,選擇相對小的元素放入到合并空間,並移動指標到下一位置
  4. 重複步驟3直到某一指標達到序列尾
  5. 將另一序列剩下的所有元素直接複製到定序序列尾

============================================================

此時,整個歸併排序在最壞情況下所需的計算時間T(n)滿足

             T(n) =                  {          O(1)                              n <= 1

                                          {         2T(n/2)+O(n)               n > 1

             解此遞迴方程可得  T(n)  = O(nlogn)   ,由於排序問題的計算時間下界為nlogn,故歸併排序演算法是一個漸進最優演算法。

2.快速排序

快速排序的思想:

演算法代碼:

template<class T>void quickSort(T arr[],int l,int r ){if(l < r){//一趟排序int t = l;T temp = arr[t];int i = l,j=r;while(i < j){for(;arr[j]>= temp && i<j ;j-- ){}if(arr[j]< temp && i<j){//交換arr[t] = arr[j];t = j;i++;}for(;arr[i]<= temp && i<j ; i++){}if(arr[i] > temp && i<j){arr[t] = arr[i];t = i;j--;}}arr[i] = temp;t = i;//遞迴調用,分解問題quickSort(arr,l,t-1);quickSort(arr,t+1,r);}}

時間複雜度:O(nlogn)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.