so true

          心懷未來,開創(chuàng)未來!
          隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
          數(shù)據(jù)加載中……

          一個較為復(fù)雜的二路歸并算法

          /*

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

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

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

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

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

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

          */

          #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;//這只給出一個推薦位置,也即最相關(guān)位置,在后續(xù)應(yīng)用該結(jié)果時,需要做分析處理
          }

          void movedata(int a[],int pos,int h,int t){//該函數(shù)用于將[h,t]區(qū)間內(nèi)的數(shù)據(jù)移動到pos指定的插入位置
           int s;
           if(pos>t){//插入點(diǎn)在后方
            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){//插入點(diǎn)在前方
            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)//該函數(shù)用于兩路合并,h和t分別表示頭部和尾部
          {
           if( h1>t1 || h2>t2 )return;
           int i_pos=-1,s_end=-1;
           if(a[h1]<=a[h2]){//確保都是為一個大數(shù)查找插入的位置
            i_pos=find2fenfa(a,h1,t1,a[h2]);
            a[i_pos]<=a[h2] ? i_pos++ : i_pos;//根據(jù)推薦位置對應(yīng)的數(shù)值大小來調(diào)整合適的插入點(diǎn)
            if(i_pos>t1)return;//已經(jīng)有序,不必再合并了
            s_end=find2fenfa(a,h2,t2,a[i_pos]);//為待插入的部分找到一個終點(diǎn),起始點(diǎn)已經(jīng)由h2來標(biāo)記了
            a[s_end]>=a[i_pos] ? s_end-- : s_end;//微調(diào),很必要的
            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){//兩路歸并,這個函數(shù)主要是為merge2函數(shù)每次分配合適的兩路
           int x=1;//表示當(dāng)前進(jìn)行的兩路歸并中的“路的長度”
           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;
           
          }

           

          單次運(yùn)行結(jié)果為:

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

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

          評論

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

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

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

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

          好聰明的作者!長見識了!
          請問在哪高就啊?
          2008-10-04 19:51 | yball
          主站蜘蛛池模板: 新巴尔虎左旗| 佳木斯市| 枞阳县| 上高县| 赤峰市| 社旗县| 涪陵区| 南漳县| 信宜市| 崇仁县| 宝山区| 门头沟区| 翁牛特旗| 隆昌县| 芮城县| 思茅市| 横峰县| 井研县| 岢岚县| 洛阳市| 阿克陶县| 嵊泗县| 绵阳市| 科技| 泉州市| 桃源县| 加查县| 民乐县| 临西县| 盖州市| 汶上县| 平舆县| 福泉市| 玉门市| 石河子市| 三原县| 江安县| 株洲县| 金山区| 邯郸县| 从江县|