• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            熱轉印www.yxheatpress.com

            公司網站模板http://qiyemoban.software8.co/

            常用鏈接

            統計

            友情鏈接

            最新評論

            數據結構:勝者樹與敗者樹

            假設有k個稱為順串的有序序列,我們希望將他們歸并到一個單獨的有序序列中。每一個順串包含一些記錄,并且這些記錄按照鍵值的大小,以非遞減的順序排列。令n為k個順串中的所有記錄的總數。并歸的任務可以通過反復輸出k個順串中鍵值最小的記錄來完成。鍵值最小的記錄的選擇有k種可能,它可能是任意有一個順串中的第1個記錄。并歸k個順串的最直接的辦法就是進行k-1次比較確定下一個輸出的記錄。對k>2,我們可以通過使用選擇數這種數據結構來降低尋找下一個最小元素所需要進行的比較次數。有兩個種選擇樹:勝利樹和失敗樹。

            勝者樹與敗者樹是完全二叉樹。就像是參加比賽一樣,每個選手有不同的實力,兩個選手PK,實力決定勝負,晉級下一輪,經過幾輪之后,就能得到冠軍。不同的是,勝者樹的中間結點記錄的是勝者的標號;而敗者樹的中間結點記錄的敗者的標號。 勝者樹與敗者樹可以在log(n)的時間內找到最值。任何一個葉子結點的值改變后,利用中間結點的信息,還是能夠快速地找到最值。在k路歸并排序中經常用到。

            一、勝者樹

            勝者樹的一個優點是,如果一個選手的值改變了,可以很容易地修改這棵勝者樹。只需要沿著從該結點到根結點的路徑修改這棵二叉樹,而不必改變其他比賽的結果。下面是選擇一個最小的數字為最勝利者(見圖1所示),第一次把各個數組里面的第一個元素都放進去,這是根據勝利樹的規則兩兩比較,得到最小的值,第一次弄完之后,就得出1數字是勝利的,也就是1是最小的。在下一次輸出第二小的數字時候,只需要把1所在的數組里面的元素加進去,然后從葉子節點到根節點一直比較得出第二小的值,這樣就減少了很多次無用的比較(見圖2所示)。

                                    

            圖 一                                                                                                               圖二

            問題:有20個有序數組,每個數組有500個uint變量,降序排序。要求從這10000個元素中選出最大的500個。

            程序:

            1. #include <iostream>  
            2. #include <vector>  
            3. #include <cmath>  
            4. #include <ctime>  
            5. #include <algorithm>  
            6.   
            7. /** 
            8. *    
            9. *   Author: w397090770 
            10. *   Data  : 2012.10.15 
            11. *   Email : wyphao.2007@163.com 
            12. *   轉載請注明出處,謝謝。  
            13. *        
            14. */   
            15. #define N 10  
            16. #define INF (1 << 31) - 1  
            17. using namespace std;  
            18.   
            19. typedef struct Node{  
            20.     int which;  //記錄是哪個子數組   
            21.     int index;  //記錄是上個標記數組的第幾個元素了   
            22.     int data;   //記錄數組的元素   
            23. }Node;  
            24.   
            25. int com(const void *a, const void *b){  
            26.     if(*(int *)a > *(int *)b){  
            27.         return 1;  
            28.     }else if(*(int *)a < *(int *)b){  
            29.         return -1;  
            30.     }  
            31.       
            32.     return 0;  
            33. }  
            34.   
            35. void adjustTreeForFirst(Node *tempArray, int len){  
            36.     int i = len / 2;  
            37.     int j = 0;  
            38.     while(i > 1){  
            39.         for(j = i; j < 2 * i - 1; j += 2){  
            40.             if(tempArray[j].data > tempArray[j + 1].data){  
            41.                 tempArray[j / 2] = tempArray[j + 1];  
            42.             }else{  
            43.                 tempArray[j / 2] = tempArray[j];  
            44.             }  
            45.         }  
            46.         i /= 2;  
            47.     }  
            48. }  
            49.   
            50. //col 是列  
            51. //row 是行  
            52. //len 是選擇出前多少個元素   
            53. void winTree(int **a, int row, int col, int len){  
            54.     int *result = (int *)malloc(len * sizeof(int));  
            55.     Node tempArray[row * 2];  
            56.     int index = 0;  
            57.     int i = 0, j = 0;  
            58.     memset(tempArray, 0, sizeof(struct Node) * 2 * row);  
            59.       
            60.     for(i = 0; i < row; i++){  
            61.         tempArray[row + i].data = a[i][0];  
            62.         tempArray[row + i].which = i;  
            63.         tempArray[row + i].index = 0;  
            64.     }  
            65.       
            66.     for(i = 0 ; i < len; i++){  
            67.         adjustTreeForFirst(tempArray, 2 * row);//為了代碼減少代碼量,我把每一次調用都調整整個樹,其實是不必要的,有興趣的用戶可以自己寫寫  
            68.         result[i] = tempArray[1].data;  
            69.         if(tempArray[1].index + 1 < col){  
            70.             tempArray[row + tempArray[1].which].data = a[tempArray[1].which][tempArray[1].index + 1];  
            71.             tempArray[row + tempArray[1].which].index = tempArray[1].index + 1;  
            72.             tempArray[row + tempArray[1].which].which = tempArray[1].which;  
            73.         }else{//如果某個數組里面的數據處理完了,就把那個節點賦值為無窮大   
            74.             tempArray[row + tempArray[1].which].data = INF;  
            75.             //tempArray[row + tempArray[1].which].index = tempArray[1].index + 1;  
            76.             //tempArray[row + tempArray[1].which].which = tempArray[1].which;  
            77.         }         
            78.     }  
            79.       
            80.     for(i = 0; i < len; i++){  
            81.         cout << result[i] << endl;  
            82.     }   
            83.     free(result);  
            84. }  
            85.   
            86. int main(){  
            87.     /*int a[N - 2][N] = { 
            88.         3, 4, 5, 6, 10, 11, 12, 13, 20, 21, 
            89.         1, 2, 7, 8, 9, 30, 31, 32, 33, 34, 
            90.         14, 15, 16, 17, 18, 19, 22, 23, 24, 25, 
            91.         26, 27, 28, 29, 35, 36, 37, 38, 39, 40, 
            92.         50, 51, 52, 54, 55, 65, 66, 67, 68, 69, 
            93.         53, 56, 57, 58, 59, 60, 61, 62, 63, 64, 
            94.         41, 42, 43, 44, 45, 46, 47, 48, 49, 2222, 
            95.         1, 2, 2, 4, 5, 6, 12, 13, 20, 21 
            96.     };*/  
            97.     const int size = 500;  
            98.     const int del = 20;  
            99.       
            100.     int *a[del];  
            101.     int i = 0, j = 0;  
            102.     //分配內存空間   
            103.     for(i = 0; i < del; i++){  
            104.         a[i] = (int *)malloc(size * sizeof(int));     
            105.     }  
            106.       
            107.     //初始化數組   
            108.     srand( time(NULL) );   
            109.     for(i = 0; i < size; i++){  
            110.         for(j = 0; j < del; j++){  
            111.             a[j][i] = rand();  
            112.         }     
            113.     }  
            114.       
            115.     //排序   
            116.     for(i = 0; i < del; i++){  
            117.         qsort(a[i], size, sizeof(int), com);  
            118.     }  
            119.       
            120.     //利用勝利樹進行處理   
            121.     winTree(a, del, size, size);  
            122.     return 0;  
            123. }  

            二、敗者樹

            敗者樹是勝者樹的一種變體。在敗者樹中,用父結點記錄其左右子結點進行比賽的敗者,而讓勝者參加下一輪的比賽。敗者樹的根結點記錄的是敗者,需要加一個結點來記錄整個比賽的勝利者。采用敗者樹可以簡化重構的過程。


            posted on 2012-10-16 14:21 不聽話的 閱讀(1955) 評論(1)  編輯 收藏 引用

            評論

            # re: 數據結構:勝者樹與敗者樹 2013-09-11 18:00 lxl

            代碼應該是選出最小的500個元素吧  回復  更多評論   

            久久人人爽人人爽人人片AV不 | 国产综合久久久久久鬼色| 久久人人爽人人人人片av| 新狼窝色AV性久久久久久| 97久久精品国产精品青草| 日批日出水久久亚洲精品tv| 人妻无码精品久久亚瑟影视 | 精品熟女少妇aⅴ免费久久| 思思久久99热只有频精品66| 国产精品青草久久久久婷婷 | 伊人久久大香线蕉综合影院首页| 国产精品久久自在自线观看| 亚洲精品无码久久久| 久久婷婷久久一区二区三区| 国产毛片欧美毛片久久久| 精品人妻伦九区久久AAA片69| 国内精品久久久久伊人av| 亚洲午夜精品久久久久久浪潮 | 久久高清一级毛片| 久久丫精品国产亚洲av| 久久精品国产亚洲av麻豆图片| 久久国产亚洲精品麻豆| 亚洲国产另类久久久精品| 日本亚洲色大成网站WWW久久| 久久久青草久久久青草| 无码AV波多野结衣久久| 热99RE久久精品这里都是精品免费| 91久久精品视频| 亚洲国产精品久久久久久| 国产精品久久成人影院| a高清免费毛片久久| 丁香狠狠色婷婷久久综合| 91精品国产高清91久久久久久| 国产情侣久久久久aⅴ免费| 久久人妻无码中文字幕| 超级97碰碰碰碰久久久久最新| 免费一级做a爰片久久毛片潮 | 狠狠色综合久久久久尤物| 精品国产一区二区三区久久| 久久综合给合久久狠狠狠97色69| 成人久久免费网站|