问题描述:
由前序遍历和中序遍历重建二叉树(前序序列:1 2 3 4 5 6 - 中序序列:3 2 4 1 6 5)数据不含重复值。
题目分析如下:
前序遍历序列1 2 3 4 5 6,前序遍历规则是根--左--右。
中序遍历序列3 2 4 1 6 5,中序遍历规则是左--根--右
1.由前序遍历可知根节点一定为第一个元素1,在中序遍历序列中找到1对应位置,判断根节点1的左右子树是否为空,1的左右都不为空,1的左边就是左子树324,右边就是右子树56;
2.再根据前序遍历规则可知,左子树序列里第一个就是左子树的根节点2,右子树序列里的第一个就是右子树的根节点5,用上次的方法递归建立左右子树。
3.再根据中序遍历序列可知,左子树的根节点2左边的一定是以其为根节点的左子树序列3,右边就是以其为根节点的右子树序列4,
右子树的根节点5左边的一定是以其为根节点的右子树序列6,直至序列为空,就可以完整重建二叉树了
代码实现:
#include<iostream> #include<cassert> using namespace std; struct NewTreeNode { NewTreeNode* _left; NewTreeNode* _right; int _value; NewTreeNode(int value) :_value(value) ,_left(NULL) ,_right(NULL) {} }; typedef NewTreeNode Node; Node* _RebuildTree(int *startPre,int *endPre,int *startIn,int *endIn) { Node *root = new Node(startPre[0]); //_left和_right已初始化为NULL if(startIn == endIn && *startIn == *startIn) { return root; } //4.根据此根节点在中序中找此节点的位置 int * rootIn = startIn; while(*startPre != *rootIn) { rootIn++; } //根据此根节点在中序遍历中的位置,递归还原左子树 int leftlen = rootIn-startIn; if(leftlen>0) { root->_left = _RebuildTree(startPre+1,startPre+leftlen,startIn,startIn+leftlen-1); } if(leftlen+startIn < endIn)//该节点还存在右子树,所以继续递归还原右子树 {//递归还原右子树 root->_right = _RebuildTree(startPre+leftlen+1,endPre,startIn+leftlen+1,endIn); } return root; } Node* RebuildTree(int* PreOrder,int* InOrder,int len) { if(PreOrder == NULL || InOrder == NULL ) return NULL; else return _RebuildTree(PreOrder,PreOrder+len-1,InOrder,InOrder+len-1); } void PostOrder(Node *root) { if(root->_left != NULL) PostOrder(root->_left); if(root->_right != NULL) PostOrder(root->_right); cout<<root->_value<<" "; } void PrevOrder(Node *root) { if(root==NULL) return; cout<<root->_value<<" "; if(root->_left != NULL) PrevOrder(root->_left); if(root->_right != NULL) PrevOrder(root->_right); } int main() { int PreOrder[] = {1,2,3,4,5,6}; int InOrder[] = {3,2,4,1,6,5}; int PreSize=sizeof(PreOrder)/sizeof(PreOrder[0]); int InSize=sizeof(InOrder)/sizeof(InOrder[0]); if(PreSize!=InSize) { cout<<"所给数据错误"<<endl; return -1; } NewTreeNode* root = RebuildTree(PreOrder,InOrder,PreSize); PrevOrder(root);//123456 cout<<endl; PostOrder(root);//342651 cout<<endl; system("pause"); return 0 ; } 在此运用前序和后序检查该树是否正确
运行结果:
未完,后续还有部分关于二叉树面试题!待续!
