<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 閱讀(498) 評論(2)  編輯  收藏 所屬分類: C&C++

    評論

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

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

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

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

    好聰明的作者!長見識了!
    請問在哪高就啊?
    2008-10-04 19:51 | yball
    主站蜘蛛池模板: 久久亚洲精品国产亚洲老地址 | 亚洲愉拍99热成人精品热久久 | 狠狠久久永久免费观看| 亚洲一级免费毛片| 国产一卡二卡四卡免费| 亚洲性无码av在线| 在线观看免费毛片| 丰满亚洲大尺度无码无码专线 | 国产成人免费ā片在线观看| 亚洲人成人无码.www石榴| 在线a人片天堂免费观看高清| 亚洲色偷偷色噜噜狠狠99| 国产精品二区三区免费播放心| 亚洲欧美国产精品专区久久| 国产男女猛烈无遮挡免费视频| 欧洲乱码伦视频免费国产| 色噜噜亚洲精品中文字幕| 日韩精品免费在线视频| 久久夜色精品国产噜噜噜亚洲AV | 99精品视频在线观看免费播放 | 亚洲成av人片天堂网老年人| 一本一道dvd在线观看免费视频| 亚洲日韩精品一区二区三区 | 免费无码又爽又高潮视频| 国产亚洲福利精品一区二区| 亚洲午夜激情视频| 久久w5ww成w人免费| 亚洲综合精品第一页| 狠狠亚洲婷婷综合色香五月排名| 久久久精品午夜免费不卡| 亚洲国产精品久久网午夜| 国产午夜无码视频免费网站| 中文字幕在线观看免费| 亚洲最大在线观看| 亚洲 综合 国产 欧洲 丝袜| 免费黄网站在线观看| 亚洲日本成本人观看| 亚洲成a人片在线观看无码| 性做久久久久久久免费看| 一区二区三区免费精品视频| 亚洲美女色在线欧洲美女|