剑指Offer面试题7:重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{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<<" ";
}

运行结果如下:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值