• <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>
            隨筆-80  評論-24  文章-0  trackbacks-0
            假設已經有了前序遍歷和中序遍歷的結果,希望通過一個算法重建這棵樹。已知遍歷結果為字符串,且樹的每個節點的value都是一個字符,且各不相同。
            如,前序:a b d c e f
            中序:d b a e c f
            則由前序可知,樹的根必定是前序遍歷的第一個節點a,再找a在中序中的位置,則可知道中序遍歷中a之前的所有節點都是a的左子樹,這樣,就可以遞歸建立左子樹,同樣中序遍歷中a右邊的序列是a的右子樹,遞歸建立即可。
            代碼如下:

             1 struct NODE {
             2   NODE* left;
             3   NODE* right;
             4   char value;
             5 };
             6 
             7 void rebuild_bitree(char *pre_order, 
             8     char *in_order, 
             9     int treelen, 
            10     NODE **root) {
            11   assert(root != NULL);
            12   if (pre_order == NULL ||  
            13       in_order == NULL ||  
            14       treelen <= 0) {
            15     return;
            16   }
            17   if (*root == NULL) {
            18     *root = new NODE;
            19   }
            20   (*root)->value = pre_order[0];
            21   (*root)->left = (*root)->right = NULL;
            22   int i = 0;
            23   for (i = 0; i < treelen; ++i) {
            24     if (in_order[i] == pre_order[0]) {
            25       break;
            26     }   
            27   }
            28   rebuild_bitree(pre_order + 1,  
            29       in_order, 
            30       i,  
            31       &((*root)->left));
            32   rebuild_bitree(pre_order + i + 1,  
            33       in_order + i + 1,  
            34       treelen - i - 1,  
            35       &((*root)->right));
            36 }

            如果已經知道了中序遍歷結果和后序遍歷結果,那么如何重構二叉樹呢?其實仔細想想,它和知道前序和中序來構造二叉樹的原理是一樣,只不過后序的根節點在序列的最后,只要知道根節點那么就可以去掃描中序序列,然后確定左子樹和右子樹,代碼如下:

             1 void rebuild_bitree(char *in_order, 
             2     char *post_order, 
             3     int treelen, 
             4     NODE **root) {
             5   if (in_order == NULL || 
             6       post_order == NULL || 
             7       treelen <= 0) {
             8     return;
             9   }
            10 
            11   if (*root == NULL) {
            12     *root = new NODE;
            13   }
            14   (*root)->value = post_order[treelen - 1];
            15   (*root)->left = (*root)->right = NULL;
            16 
            17   int i = 0;
            18   for (i = 0; i < treelen; ++i) {
            19     if (in_order[i] == post_order[treelen - 1]) {
            20       break;
            21     }
            22   }
            23 
            24   rebuild_bitree(in_order, 
            25       post_order, 
            26       i, 
            27       &(*root)->left);
            28   rebuild_bitree(in_order + i + 1, 
            29       post_order + i, 
            30       treelen - i - 1, 
            31       &(*root)->right);
            32 }

            上面寫出的都是遞歸算法,因為遞歸本質上就是利用棧來操作,所以,如果要采用非遞歸算法來實現的話該如何做呢?現在還是以知道后序和中序,來重建二叉樹,還是前面的例子:
            中序:d b a e c f 
            后序:d b e f c a
            1、還是先用一個棧保存后序中的節點在中序中的索引值,初始棧為空
            2、對后序從后向前掃描,1)若棧為空,則該節點直接入棧;2)若當前節點在中序中的索引值大于棧頂節點在中序中的索引值,則可知該節點為棧頂節點的右孩子;3)只要當前節點在中序中的索引值小于棧頂 節點在中序節點中的索引值,就連續出棧,當前節點是最后一個出棧節點的左孩子;
            這樣程序如下:

             1 void rebuild_bitree(char *in_order,                                                                               
             2     char *post_order, 
             3     int treelen, 
             4     NODE **root) {
             5   if (in_order == NULL || post_order == NULL || treelen <= 0) {
             6     return;
             7   }
             8   if (*root == NULL) {
             9     *root = new NODE;
            10     (*root)->value = post_order[treelen - 1];
            11     (*root)->left = (*root)->right = NULL;
            12   }
            13   std::stack<int> index_stack;
            14   std::stack<NODE *> node_stack;
            15   int i;
            16   int j;
            17   NODE *tmp1;
            18   NODE *tmp2;
            19   for (i = treelen - 1; i >= 0; --i) {
            20     if (i == treelen - 1) {
            21       tmp1 = *root;
            22     } else {
            23       tmp1 = new NODE;
            24       tmp1->value = post_order[i];
            25       tmp1->left = tmp1->right = NULL;
            26     }
            27     for (j = 0; j < treelen; ++j) {
            28       if (in_order[j] == post_order[i]) {
            29         break;
            30       }
            31     }
            32     if (index_stack.empty()) {
            33       index_stack.push(j);
            34       node_stack.push(tmp1);
            35     } else if (j > index_stack.top()) {
            36       node_stack.top()->right = tmp1;
            37       index_stack.push(j);
            38       node_stack.push(tmp1);
            39     } else {
            40       while (!index_stack.empty() && j < index_stack.top()) {
            41         index_stack.pop();
            42         tmp2 = node_stack.top();
            43         node_stack.pop();
            44       }
            45       tmp2->left = tmp1;
            46       index_stack.push(j);
            47       node_stack.push(tmp1);
            48     }
            49   }

            由前序和中序重構二叉樹的非遞歸算法和上面相似,就是對前序由前向后掃描,具體算法就不寫出來了
            posted on 2012-09-03 14:24 myjfm 閱讀(551) 評論(0)  編輯 收藏 引用 所屬分類: 算法基礎
            91精品国产高清久久久久久io| 伊人热热久久原色播放www| 久久精品中文无码资源站| 香蕉久久av一区二区三区| 久久成人国产精品| 国产成人综合久久精品尤物| 久久久久久久久66精品片| 丁香五月网久久综合| 国产精品久久久久久久久久免费| 久久久久久极精品久久久| 综合久久给合久久狠狠狠97色| 7777精品久久久大香线蕉| 久久精品国产亚洲麻豆| 免费一级欧美大片久久网 | 亚洲性久久久影院| 久久综合综合久久综合| 狠狠色伊人久久精品综合网 | 久久久久久国产精品无码下载| 久久免费看黄a级毛片| 91久久精品无码一区二区毛片| 久久婷婷五月综合国产尤物app| 国产精品久久久久久福利69堂| 亚洲国产高清精品线久久| 久久国产一区二区| 无码超乳爆乳中文字幕久久 | 久久艹国产| 久久这里只有精品久久| 亚洲精品乱码久久久久久自慰| 久久综合视频网站| 99精品伊人久久久大香线蕉| 国产精品久久久久9999高清| 久久久噜噜噜久久中文福利| 国产精品成人久久久| 国产精品一区二区久久精品涩爱 | 精品人妻伦九区久久AAA片69| 亚洲伊人久久大香线蕉苏妲己| 欧美喷潮久久久XXXXx| 99精品久久精品一区二区| 久久精品中文字幕一区| 伊人情人综合成人久久网小说| 久久免费大片|