• <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)  編輯 收藏 引用 所屬分類: 算法基礎
            久久av免费天堂小草播放| 91久久九九无码成人网站| 综合久久一区二区三区 | 亚洲精品tv久久久久久久久久| 久久精品国产亚洲7777| 亚洲va中文字幕无码久久| 久久96国产精品久久久| 久久精品一本到99热免费| 成人资源影音先锋久久资源网| 久久99精品久久只有精品| 97久久精品无码一区二区| 久久精品国产亚洲Aⅴ香蕉| 亚洲精品美女久久777777| 精品久久久久久国产牛牛app| 久久精品中文字幕一区| 久久精品成人免费国产片小草| 亚洲AV无码久久| 久久综合九色综合欧美就去吻| 国内精品久久九九国产精品| 久久人人添人人爽添人人片牛牛| www.久久99| 久久久久se色偷偷亚洲精品av| 一本一道久久精品综合| 性欧美大战久久久久久久久| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 亚洲∧v久久久无码精品| 久久精品国产精品亜洲毛片| 久久久久久无码Av成人影院| 性欧美丰满熟妇XXXX性久久久| 精品国产乱码久久久久软件| 一级做a爰片久久毛片免费陪 | 欧美精品福利视频一区二区三区久久久精品 | 成人综合久久精品色婷婷| 国产精品久久成人影院| 亚洲中文字幕无码久久2020| 亚洲国产成人久久综合碰| 久久精品99无色码中文字幕| 2020最新久久久视精品爱| 久久99精品久久久久久9蜜桃| 国产—久久香蕉国产线看观看 | 欧美激情一区二区久久久|