剑指offer——重建二叉树(7题)

给定前序遍历序列和中序遍历序列,恢复出二叉树。前序序列{1,2,4,7,3,5,6,8},中序序列{4,7,2,1,5,3,8,6}

其复原思想:

利用递归思想,

前序找根结点,利用中序确定左子树结点个数和右子树的结点个数。

接着从前序中分别递归到左右子树中去重建二叉树。

递归的结束条件只剩一个结点且前序和中序所指向的是同一结点。

代码见下:

#include<iostream>
#include<vector>

using namespace std;

struct TreeNode {
	int val;
	TreeNode* left, *right;
	TreeNode(int x):val(x),right(nullptr),left(nullptr){}
};

TreeNode* construct(vector<int>& preOrder, int pStart, int pEnd,
					vector<int>& inOrder, int iStart, int iEnd) {
	TreeNode* root = new TreeNode(preOrder[pStart]);

	//设置递归终止条件
	if (pStart == pEnd) {
		if (iStart == iEnd&&preOrder[pStart] == inOrder[iStart])
			return root;
	}
	//计算左子树节点的个数
	int leftLen = 0;
	for (int i = iStart; inOrder[i] != preOrder[pStart]; ++i)
		++leftLen;
	
	//分别递归左右子树,构建树。。。写以下序号参数的填写最好能图形结合
	if (leftLen > 0)//判断左子树非空
		root->left = construct(preOrder, pStart + 1, pStart + leftLen, inOrder, iStart, iStart + leftLen - 1);
	if (leftLen < pEnd - pStart)//判断右子树非空
		root->right = construct(preOrder, pStart + leftLen + 1, pEnd, inOrder, iStart + leftLen + 1, iEnd);

	return root;
}

TreeNode* reBuildBinaryTree(vector<int>& preOrder, vector<int>& inOrder) {
	if (preOrder.empty() || inOrder.empty() || preOrder.size() != inOrder.size())
		return nullptr;
	return construct(preOrder, 0, preOrder.size() - 1, inOrder, 0, inOrder.size() - 1);
}

//用来验证构建二叉树是否正确
void preOrder(TreeNode* root) {
	if (root == nullptr) {
		return;
	}
	cout << root->val << endl;
	if (root->left)
		preOrder(root->left);
	if (root->right)
		preOrder(root->right);
}
int main() {
	vector<int> preO = { 1,2,4,7,3,5,6,8 };
	vector<int> inO = { 4,7,2,1,5,3,8,6 };
	TreeNode* root = reBuildBinaryTree(preO, inO);
	preOrder(root);
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值