<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    so true

    心懷未來,開創未來!
    隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
    數據加載中……

    一個較為復雜的二路歸并算法

    /*

    作者:bacoo
    日期:2008年9月21日

    一個比較復雜的二路歸并排序算法,完成由小到大的排序功能

    算法摒除了最初始的“從兩路頭部依次取出數據,經過比較后輸出較小值”方法;

    而是找出“頭大”的一路,然后把另一路分成許多片斷,然后插入到“頭大”的那路中,

    這里面尋找插入點使用了二分法查找以提高效率,

    需要說明的是,該算法在兩部“交錯”不是很嚴重的情況下有較好的效率。

    */

    #include <iostream>
    using namespace std;

    int find2fenfa(int a[],int h,int t,int num){//利用二分法來查找num的位置,要求在[h,t]之間
     while(h<t){
      int m=(h+t)/2;
      if(num==a[m]){
       return m;
      }
      else if(num<a[m])
       t=m-1;
      else
       h=m+1;
     }
     return h;//這只給出一個推薦位置,也即最相關位置,在后續應用該結果時,需要做分析處理
    }

    void movedata(int a[],int pos,int h,int t){//該函數用于將[h,t]區間內的數據移動到pos指定的插入位置
     int s;
     if(pos>t){//插入點在后方
      for(int i=t;i>=h;i--){
       s=a[i];
       for(int j=i;j<pos-1;j++){
        a[j]=a[j+1];
       }
       a[--pos]=s;
      }
     }
     else if(pos<h){//插入點在前方
      for(int i=h;i<=t;i++){
       s=a[i];
       for(int j=i;j>pos;j--){
        a[j]=a[j-1];
       }
       a[pos++]=s;
      }
     }
    }

    void merge2(int a[],int h1,int t1,int h2,int t2)//該函數用于兩路合并,h和t分別表示頭部和尾部
    {
     if( h1>t1 || h2>t2 )return;
     int i_pos=-1,s_end=-1;
     if(a[h1]<=a[h2]){//確保都是為一個大數查找插入的位置
      i_pos=find2fenfa(a,h1,t1,a[h2]);
      a[i_pos]<=a[h2] ? i_pos++ : i_pos;//根據推薦位置對應的數值大小來調整合適的插入點
      if(i_pos>t1)return;//已經有序,不必再合并了
      s_end=find2fenfa(a,h2,t2,a[i_pos]);//為待插入的部分找到一個終點,起始點已經由h2來標記了
      a[s_end]>=a[i_pos] ? s_end-- : s_end;//微調,很必要的
      movedata(a,i_pos,h2,s_end);
      merge2(a,i_pos+s_end-h2,s_end,s_end+1,t2);
     }else{
      i_pos=find2fenfa(a,h2,t2,a[h1]);
      a[i_pos]<=a[h1] ? i_pos++ : i_pos;
      if(i_pos>t2){
       movedata(a,h1,h2,t2);
       return;
      }
      s_end=find2fenfa(a,h1,t1,a[i_pos]);
      a[s_end]>=a[i_pos] ? s_end-- : s_end;
      movedata(a,i_pos,h1,s_end);
      merge2(a,h1,t1-(s_end-h1+1),t1-s_end+h1,t2);
     }
    }

    void sort_2way(int a[],int len){//兩路歸并,這個函數主要是為merge2函數每次分配合適的兩路
     int x=1;//表示當前進行的兩路歸并中的“路的長度”
     int h1,t1,h2,t2;
     while(x<=len){
      for(int i=0;i<len;i+=2*x){
       h1=i;
       h2=i+x;
       t1=h2-1;
       t2=h2+x-1;
       if(h2>=len)continue;
       else{
        if(t2>=len){
         merge2(a,h1,t1,h2,len-1);
         break;
        }else
         merge2(a,h1,t1,h2,t2);
       }
      }
      x*=2;
     }
    }

    void main(){
     int a[10];
     int len=sizeof(a)/sizeof(a[0]);
     for(int i=0;i<len;i++)a[i]=rand()%100;

     sort_2way(a,len);
     
     for(i=0;i<len;i++)cout<<a[i]<<endl;
     
    }

     

    單次運行結果為:

    0
    24
    34
    41
    58
    62
    64
    67
    69
    78
    Press any key to continue

    posted on 2008-09-21 01:21 so true 閱讀(499) 評論(2)  編輯  收藏 所屬分類: C&C++

    評論

    # re: 一個較為復雜的二路歸并算法  回復  更多評論   

    首先聲明一下:我是本文的作者。
    寫完這個代碼之后,到網上檢索了一下二路歸并算法的實現,大多數都是最原始的那種做法,而其還需要輔助數組,其實我覺得也可以完全不用輔助數組,不過這就是空間與時間的矛盾之處,因為不用輔助數組的話需要大量的移動數據,造成時間復雜度的提高。

    后來我回顧了一下我給出的算法,雖然編寫調試了很長時間才最終成功,但是依然很欣慰,好似還沒有其他人這么做,難道我有如此聰明?不至于吧,呵呵,反正竊喜一下,凌晨2點,睡覺去^_^
    ………………
    2008-09-21 02:03 | bacoo

    # re: 一個較為復雜的二路歸并算法  回復  更多評論   

    好聰明的作者!長見識了!
    請問在哪高就?。?
    2008-10-04 19:51 | yball
    主站蜘蛛池模板: 亚洲精品无码久久久久去q| 国产精品视频免费观看| 91成人免费福利网站在线| 国产精品内射视频免费| 日韩高清免费在线观看| 国产精品成人啪精品视频免费| 青青免费在线视频| 日本特黄特色AAA大片免费| 青青草国产免费国产是公开| 少妇亚洲免费精品| 国产精品九九久久免费视频 | 亚洲伦另类中文字幕| 最近免费中文字幕大全视频| 一二三四视频在线观看中文版免费| 美女视频黄是免费的网址| www.999精品视频观看免费| 成人黄动漫画免费网站视频| 国产片免费福利片永久| 色se01短视频永久免费| 成年性午夜免费视频网站不卡| 日韩精品视频免费网址| 亚洲色偷偷综合亚洲AV伊人| 亚洲成A人片777777| 亚洲国产精品尤物YW在线观看 | 国产AV日韩A∨亚洲AV电影| 免费夜色污私人影院网站| 黄桃AV无码免费一区二区三区| 久久亚洲中文字幕无码| 亚洲一区二区三区免费视频| 久久精品亚洲中文字幕无码网站 | 亚洲成AⅤ人影院在线观看| 亚洲午夜久久久影院| 亚洲精品在线播放视频| 亚洲精品无码mⅴ在线观看| 亚洲色图.com| 亚洲成a人片在线观看天堂无码 | 亚洲影院天堂中文av色| 成人a毛片视频免费看| 亚洲免费在线播放| 永久免费看mv网站入口| 免费毛片在线看片免费丝瓜视频|