• <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 閱讀(556) 評論(0)  編輯 收藏 引用 所屬分類: 算法基礎
            久久久久亚洲av成人网人人软件| 精品国产乱码久久久久久1区2区| 国产成人久久777777| 精品人妻伦一二三区久久| 久久伊人色| 久久被窝电影亚洲爽爽爽| 亚洲午夜精品久久久久久app| 亚洲精品乱码久久久久久久久久久久 | 亚洲国产精品无码久久久不卡| 精品国产福利久久久| 日韩精品无码久久一区二区三| 久久天天躁狠狠躁夜夜躁2O2O| 久久99热这里只有精品国产| 国产精品9999久久久久| 国内精品伊人久久久影院| 国产精品成人精品久久久| 日产精品久久久久久久| 亚洲人成无码www久久久| 久久久久免费精品国产| 久久久久亚洲AV无码网站| 久久天天婷婷五月俺也去 | 久久久久亚洲av毛片大| 久久超乳爆乳中文字幕| 99久久精品国产一区二区| 热RE99久久精品国产66热| 久久免费视频观看| 久久99国产精品久久99| 国产精品久久久久国产A级| 久久精品国产精品亚洲精品| 欧美一区二区久久精品| 色8激情欧美成人久久综合电| 久久精品国产一区二区电影| 久久99精品免费一区二区| Xx性欧美肥妇精品久久久久久| 狠狠色丁香婷综合久久| 久久国产精品-国产精品| 粉嫩小泬无遮挡久久久久久| 777米奇久久最新地址| 91久久精品91久久性色| 久久国产精品99久久久久久老狼| 99久久精品午夜一区二区|