输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
牛客网AC代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if(pre.size() == 0)
return NULL;
TreeNode *root = new TreeNode(pre[0]);
int i = 0;
while(vin[i]!=pre[0])i++;
int lcnt = i;
vector<int> preleft,preright,vinleft,vinright;
for(int j=0;j<lcnt;j++){
preleft.push_back(pre[j+1]);
vinleft.push_back(vin[j]);
}
for(int j=lcnt+1;j<vin.size();j++){
preright.push_back(pre[j]);
vinright.push_back(vin[j]);
}
root->left = reConstructBinaryTree(preleft,vinleft);
root->right = reConstructBinaryTree(preright,vinright);
return root;
}
};
完整程序代码:
#include<iostream>
#include<exception>
using namespace std;
struct BinaryTreeNode{
int value;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
void addBTNode(BinaryTreeNode **myBT,int val);//添加节点,满足每个父亲节点大于左边的,小于右边的
void preorder_showBT(BinaryTreeNode *myBT);
void midorder_showBT(BinaryTreeNode *myBT);
void lastorder_showBT(BinaryTreeNode *myBT);
BinaryTreeNode *Construct(int *preorder,int *inorder,int length);
BinaryTreeNode *ConstructCore(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder);
int main(){
/*
BinaryTreeNode *myBT = nullptr;
addBTNode(&myBT,10);
addBTNode(&myBT,2);
addBTNode(&myBT,3);
addBTNode(&myBT,15);
addBTNode(&myBT,18);
addBTNode(&myBT,1);
addBTNode(&myBT,16);
preorder_showBT(myBT);
cout<<endl;
midorder_showBT(myBT);
cout<<endl;
lastorder_showBT(myBT);
cout<<endl;
*/
//重建二叉树
//int preList[] = {1,2,4,7,3,5,6,8};
//int inList[] = {4,7,2,1,5,3,8,6};
//int length = 8;
//int preList[] = {1, 2, 3, 4, 5};
//int inList[] = {5, 4, 3, 2, 1};
//int length = 5;
//int preList[] = {1, 2, 3, 4, 5};
//int inList[] = {1, 2, 3, 4, 5};
//int length = 5;
//int preList[] = {1, 2, 4, 5, 3, 6, 7};
//int inList[] = {4, 2, 5, 1, 6, 3, 7};
//int length = 7;
//int preList[] = {3};
//int inList[] = {3};
//int length = 1;
int preList[] = {10,3,2};
int inList[] = {10,4,2};//输入的数不一致
int length = 3;
BinaryTreeNode *root = Construct(preList,inList,length);
preorder_showBT(root);
cout<<endl;
midorder_showBT(root);
cout<<endl;
lastorder_showBT(root);
return 0;
}
BinaryTreeNode *Construct(int *preorder,int *inorder,int length)
{
if(preorder == nullptr || inorder == nullptr || length <= 0)
return nullptr;
return ConstructCore(preorder,preorder + length -1,inorder,inorder + length -1);
}
BinaryTreeNode *ConstructCore(int *startPreorder,int *endPreorder,int *startInorder,int *endInorder){
BinaryTreeNode *root = new BinaryTreeNode();
root->value = startPreorder[0];
root->m_pLeft = nullptr;
root->m_pRight = nullptr;
if(startPreorder == endPreorder){//指向同一个位置时,即到叶结点时,停止
try{
if(startInorder == endInorder && *startPreorder == *startInorder){
return root;
}
else{
throw"Invalid input--(11111111111111111).\n";
return nullptr;
}
}
catch(const char *str)
{
cout << str;
cerr <<"前序遍历与中序遍数组包含的数字不一致!\n"; //cerr不会到输出缓冲中 这样在紧急情况下也可以使用
}
}
int i=0;
while((startInorder + i) <= endInorder)
{
if( *(startInorder + i) == root->value)
break;
i++;
}
//cout<<"i = "<<i<<", root = "<<root->value<<endl;
try{
if(endInorder - (startInorder + i) <0){//递归到右子树,右子树为空时会出现异常,需要判断停止
//cout<<*endInorder<<" "<<*(startInorder + i)<<endl;
throw "Invalid input--(222222222222222).\n";
}
}
catch(const char *str)
{
cout << str;
cerr <<"前序遍历与中序遍数组包含的数字不一致!\n"; //cerr不会到输出缓冲中 这样在紧急情况下也可以使用
return nullptr;
}
int leftLength = (startInorder + i) - startInorder;
int rightLength = endInorder - (startInorder + i);
//cout<<"leftLength = "<<leftLength<<",rightLength = "<<rightLength<<endl;
//必须大于0,等于0的情况下左子树没有数据递归就会出现错误
if(leftLength > 0) //leftLength = 0时,startPreorder+1会大于startPreorder+leftLength
root->m_pLeft = ConstructCore(startPreorder+1,startPreorder+leftLength,startInorder,startInorder+leftLength-1);
//必须大于0,等于0的情况下右子树没有数据递归就会出现错误
if(rightLength > 0) //rightLength = 0时,startPreorder + leftLength) + 1会 endPreorder
root->m_pRight = ConstructCore((startPreorder + leftLength) + 1,endPreorder,(startInorder + leftLength) + 1,endInorder);
return root;
}
void addBTNode(BinaryTreeNode **myBT,int val){
if(*myBT == nullptr){
*myBT = new BinaryTreeNode();
(*myBT)->value = val;
(*myBT)->m_pLeft = nullptr;
(*myBT)->m_pRight = nullptr;
return;
}
if(val == (*myBT)->value){
return;
}
else if(val < (*myBT)->value){
addBTNode(&(*myBT)->m_pLeft,val);
}
else{
addBTNode(&(*myBT)->m_pRight,val);
}
}
void preorder_showBT(BinaryTreeNode *myBT){
if(myBT == nullptr )
return;
cout<<myBT->value<<" ";
preorder_showBT(myBT->m_pLeft);
preorder_showBT(myBT->m_pRight);
}
void midorder_showBT(BinaryTreeNode *myBT){
if(myBT == nullptr )
return;
midorder_showBT(myBT->m_pLeft);
cout<<myBT->value<<" ";
midorder_showBT(myBT->m_pRight);
}
void lastorder_showBT(BinaryTreeNode *myBT){
if(myBT == nullptr )
return;
lastorder_showBT(myBT->m_pLeft);
lastorder_showBT(myBT->m_pRight);
cout<<myBT->value<<" ";
}
运行结果如下: