• <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
            假設(shè)已經(jīng)有了前序遍歷和中序遍歷的結(jié)果,希望通過一個算法重建這棵樹。已知遍歷結(jié)果為字符串,且樹的每個節(jié)點的value都是一個字符,且各不相同。
            如,前序:a b d c e f
            中序:d b a e c f
            則由前序可知,樹的根必定是前序遍歷的第一個節(jié)點a,再找a在中序中的位置,則可知道中序遍歷中a之前的所有節(jié)點都是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 }

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

             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 }

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

             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   }

            由前序和中序重構(gòu)二叉樹的非遞歸算法和上面相似,就是對前序由前向后掃描,具體算法就不寫出來了
            posted on 2012-09-03 14:24 myjfm 閱讀(567) 評論(0)  編輯 收藏 引用 所屬分類: 算法基礎(chǔ)
            久久99中文字幕久久| 亚洲国产精品成人久久蜜臀 | 精品乱码久久久久久久| 中文无码久久精品| 国产一区二区三精品久久久无广告| 亚洲国产成人久久综合碰碰动漫3d| AA级片免费看视频久久| 伊人久久大香线蕉亚洲五月天| 国产成人久久精品一区二区三区| 久久精品夜色噜噜亚洲A∨| 亚洲中文久久精品无码| 国産精品久久久久久久| 欧美亚洲色综久久精品国产| 久久久久国产| 999久久久免费国产精品播放| 色综合合久久天天给综看| 亚洲精品高清久久| 国产高潮国产高潮久久久| 人妻无码久久一区二区三区免费| 亚洲欧美精品伊人久久| 91久久婷婷国产综合精品青草 | 久久国产亚洲精品| 色综合久久天天综合| 国产成人精品免费久久久久| 久久人人爽人人人人片av| 亚洲国产成人久久精品99| 久久精品无码一区二区app| 91亚洲国产成人久久精品| 精品亚洲综合久久中文字幕| 久久综合给合久久狠狠狠97色 | 日韩欧美亚洲综合久久影院d3| 久久中文字幕精品| 久久亚洲熟女cc98cm| 蜜桃麻豆WWW久久囤产精品| 日日狠狠久久偷偷色综合96蜜桃| 久久中文字幕一区二区| 一本一道久久精品综合| 久久亚洲国产精品123区| 亚洲精品高清一二区久久| 国产精品99久久久精品无码| 久久久久国产精品嫩草影院|