<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
    主站蜘蛛池模板: 免费jjzz在在线播放国产| 成人浮力影院免费看| jjzz亚洲亚洲女人| 亚洲精品第一国产综合亚AV| 国产亚洲精品a在线观看app| 一级毛片免费在线| 国产午夜亚洲精品国产成人小说| 久久精品国产亚洲av麻豆色欲| 亚洲精品日韩一区二区小说| 国内一级一级毛片a免费| 亚洲精品色播一区二区| 吃奶摸下高潮60分钟免费视频| 美女视频黄a视频全免费网站一区 美女视频黄a视频全免费网站色 | 好爽…又高潮了毛片免费看| 亚洲日本一线产区和二线| 日韩一区二区在线免费观看| 又粗又长又爽又长黄免费视频 | 亚洲人成电影在线观看网| 成人免费a级毛片| 国产AV无码专区亚洲AV琪琪| 久久久久亚洲AV无码专区网站| 在线观看免费视频网站色| 在线观看亚洲人成网站| 成人免费无毒在线观看网站| 男人免费视频一区二区在线观看| 日韩精品亚洲aⅴ在线影院| 久久久久久精品免费看SSS| 亚洲男同gay片| 中文字幕专区在线亚洲| 日韩精品久久久久久免费| 亚洲欧洲日韩国产一区二区三区| 四虎影视在线永久免费观看| 在线观看免费视频一区| 亚洲偷偷自拍高清| 亚洲熟女一区二区三区| 免费毛片a在线观看67194| 久久丫精品国产亚洲av不卡| 日韩a在线观看免费观看| 国产一区二区三区免费观看在线 | 亚洲中文字幕无码不卡电影| 美女被cao免费看在线看网站|