编程之美-3.9-重建二叉树

1. 简述

    给定一棵二叉树,假定每个节点都用唯一的字符表示,具体结构如下:

struct NODE {
  NODE
* pLeft;
  NODE
* pRight;
  
char chValue;
};

    假设已经有了前序遍历和中序遍历结果,希望通过一个算法重建这棵树。
    给定函数的定义如下:

void Rebuild(char* pPreOrder, char* pInOrder, int nTreeLen, NODE** pRoot);

    参数
    pPreOrder:前序遍历结果的字符串数组。
    pInOrder: 中序遍历结果的字符串数组。
    nTreeLen: 树的长度。
    pRoot:     根据前序和中序遍历结果重新构建树的根节点。
    例如
    前序遍历结果:a b d c e f
    中序遍历结果:d b a e c f

2. 思路

    递归解决相对容易些。
    递归结束条件是长度小于1,此时令*pRoot=NULL即可。
    递归主体中,在中序遍历结果中找前序结果的第一个字符,找到后记录其下标为index,如果找不到说明前序遍历和中序遍历有问题,说明错误信息,然后直接返回。找到index后,新建一个节点,让*pRoot指向它,其数值为前序的第一个字符,然后递归求*pRoot的左孩子和右孩子。
    递归左孩子:Rebuild( pPreOrder+1,pInOrder, index, &((*pRoot)->pLeft) )
    递归右孩子:Rebuild( pPreOrder+index+1, pInOrder+index+1, nTreeLen-index-1, &((*pRoot)->pRight) )

3. 代码   

#include <iostream>
#include 
<stack>
using namespace std;

struct NODE {
  NODE
* pLeft;
  NODE
* pRight;
  
char chValue;
};

void Rebuild(char* pPreOrder, char* pInOrder, int nTreeLen, NODE** pRoot) {
  
if(nTreeLen <= 0) { // 递归结束 
    *pRoot = NULL;
    
return;
  }
  
else { // 递归主体 
    int index = 0;
    
while(index < nTreeLen && pPreOrder[0]!=pInOrder[index])
      index
++;
    
if(index>=nTreeLen) {
      cout 
<< "前序和中序字符串不匹配,有问题" << endl;
      cout 
<< "在中序字符串中,找不到:" << pPreOrder[0<< endl;
      
return;
    }
    
else {
      
*pRoot = new NODE;
      (
*pRoot)->chValue = pPreOrder[0];
      Rebuild(pPreOrder
+1, pInOrder, index, &((*pRoot)->pLeft));
      Rebuild(pPreOrder
+index+1, pInOrder+index+1, nTreeLen-index-1&((*pRoot)->pRight) );
    }
  }  
}

void PrintTree(const NODE* root) { // 先根序遍历 
  stack<const NODE*> store;
  store.push(root);
  
while(!store.empty()) {
    
// output root
    cout << store.top()->chValue << ":\t";
    
// output left
    if(store.top()->pLeft == NULL)
      cout 
<< "NULL";
    
else
      cout 
<< store.top()->pLeft->chValue;
    cout 
<< " , ";
    
// output right
    if(store.top()->pRight == NULL)
      cout 
<< "NULL";
    
else
      cout 
<< store.top()->pRight->chValue;
    cout 
<< endl;
    
// push right
    const NODE* tmp = store.top();
    store.pop();
    
if(tmp->pRight)
      store.push(tmp
->pRight);
    
if(tmp->pLeft)
      store.push(tmp
->pLeft);
  }
}
int main() {
  
char* pPreOrder = "abdcef";
  
char* pInOrder = "dbaecf";
  NODE
* pRoot;
  Rebuild(pPreOrder, pInOrder, strlen(pPreOrder), 
&pRoot);
  PrintTree(pRoot);
  system(
"PAUSE");
  
return 0;
}

    输出结果为:
   

4. 参考

    编程之美,3.9节,重建二叉树

posted @ 2011-09-11 09:16  xiaodongrush  阅读(394)  评论(0编辑  收藏  举报