1. 简述
给定一棵二叉树,假定每个节点都用唯一的字符表示,具体结构如下:
NODE * pLeft;
NODE * pRight;
char chValue;
};
假设已经有了前序遍历和中序遍历结果,希望通过一个算法重建这棵树。
给定函数的定义如下:
参数
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 < 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节,重建二叉树