重建二叉树(C++)

《剑指offer》面试题7: 输入某二叉树的前序遍历中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。

例如,输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},就可以重建出下图所示的二叉树。
在这里插入图片描述
这里顺便介绍一下二叉树的四种遍历:
1、前序遍历:若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。
2、中序遍历: 若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。
3、后序遍历: 若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点。
4、层序遍历: 若树为空,则空操作返回,否则从树的第一层,也就是根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。


题解:

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

struct BinaryTreeNode
{
	int value;
	BinaryTreeNode* left;
	BinaryTreeNode* right;
};

BinaryTreeNode* ConstructCore(int* startPreorder,int* endPreorder,int* startInorder,int*){
	int rootvalue=startPreorder[0];
	BinaryTreeNode* root=new BinaryTreeNode();
	root->value=rootvalue;
	root->left=root->right=NULL;
	
	if(startPreorder==endPreorder){
		if(startInorder==endInorder && *startInorder==*startPreorder){
			return root;
		}
		else 
			throw std::exception("Invalid input.");
			//throw表达式包含关键字throw和紧随其后的一个表达式,其中表达式的类型就是抛出的异常类型。
	}
	
	int* rootInorder=startInorder;
	while(rootInorder<=endInorder && *rootInorder!=rootvalue){
		++rootInorder;
	}
	 if(rootInorder==endInorder && *rootInorder!=rootValue)
        throw std::exception("Invalid input.");
        
   	int LeftLength=rootInorder-startInorder;  //左子树节点个数 
	int* leftPreorderEnd = startPreorder + leftLength; 
    if(leftLength > 0)
    {
        // 构建左子树
        root->left = ConstructCore(startPreorder + 1, leftPreorderEnd, 
            startInorder, rootInorder - 1);
    }
    if(leftLength < endPreorder - startPreorder)
    {
        // 构建右子树
        root->right = ConstructCore(leftPreorderEnd + 1, endPreorder,
            rootInorder + 1, endInorder);
    }
    return root;           
}

需要理解的是:在代码中有很多看似加减的操作,其实都是指针的移位。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值