题目四:重建二叉树(已知前序中序和已知中序后序)

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

比如说输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出该二叉树。

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;



struct BinaryTreeNode
{
	int data;
	BinaryTreeNode *leftchild;  //左子树
	BinaryTreeNode *rightchild;  //右子树
	BinaryTreeNode(int n = 0)
	{
		data = n;
		leftchild = NULL;
		rightchild = NULL;
	}
};

//已知前序和中序重建二叉树
//先序: 根 左 右
//中序: 左 根 右
//后序: 左 右 根
//1.取先序序列第一个值,为根节点即1,在中序遍历查找这个值,那么247为左子树,3568为右子树
//2.然后再继续递归划分,先序247,中序472,那么根节点为2,以此类推。
//重复步骤12然后就可以构造出一棵二叉树了

BinaryTreeNode *PlantTree1(vector<int> pre,vector<int> in)
{
	if(pre.size() == 0 ||in.size() == 0||pre.size() != in.size())
	{
		return NULL;  //错误条件
	}
	BinaryTreeNode *root = new BinaryTreeNode(pre[0]); //先序第一个值为根节点
	int index = 0;
	vector<int> left_pre,right_pre,left_in,right_in;

	//在中序遍历找到 根节点
	for(int i = 0; i< (in.size()); i++)
	{
		if(root->data == in[i])
			index = i;
	}

	for(int i = 0; i < index; i++)
	{
		left_pre.push_back(pre[i+1]);		//根节点左子树前序遍历
		left_in.push_back(in[i]); //根节点左子树中序遍历
	}

	for(int j = index+1; j < pre.size(); j++)
	{
		right_pre.push_back(pre[j]);
		right_in.push_back(in[j]);
	}

	root->leftchild = PlantTree1(left_pre,left_in);
	root->rightchild = PlantTree1(right_pre,right_in);

	return root;
}


//已知中序和后序重建二叉树
//先序: 根 左 右
//中序: 左 根 右
//后序: 左 右 根
//1.取后序序列最后一个值,为根节点即1,在中序遍历查找这个值,那么472为左子树,5386为右子树
//2.然后再继续递归划分,中序472,后序742,那么根节点为2,以此类推。
//重复步骤12然后就可以构造出一棵二叉树了
/*
BinaryTreeNode *PlantTree2(vector<int>last,vector<int>in)
{
	if(in.size() == 0 ||last.size() == 0 || in.size() != last.size())
	{
		return NULL;
	}
	BinaryTreeNode *root = new BinaryTreeNode(last[7]); //先序第一个值为根节点
	int index = 0;
	vector<int> left_last,right_last,left_in,right_in;

	//在中序遍历找到 根节点
	for(int i = 0; i< (in.size()); i++)
	{
		if(root->data == in[i])
			index = i;
	}

	for(int i = 0; i < index; i++)
	{
		left_last.push_back(last[i]);		//根节点左子树前序遍历
		left_in.push_back(in[i]); //根节点左子树中序遍历
	}

	for(int j = index+1; j < in.size(); j++)
	{
		right_last.push_back(last[j-1]);
		right_in.push_back(in[j]);
	}

	root->leftchild = PlantTree2(left_last,left_in);
	root->rightchild = PlantTree2(right_last,right_in);

	return root;
}
*/

//先序
void PreorderTraverse(BinaryTreeNode *root)
{
	if(root)
	{
		cout << root->data << ' ';
		PreorderTraverse(root->leftchild);
		PreorderTraverse(root->rightchild);
	}
}

//中序遍历
void InorderTraverse(BinaryTreeNode *root)
{
	if(root)
	{
		InorderTraverse(root->leftchild);
		cout << root->data << ' ';
		InorderTraverse(root->rightchild);
	}
}

//后序
void LastOrderTraverse(BinaryTreeNode *root)
{
	if(root)
	{
		LastOrderTraverse(root->leftchild);
		LastOrderTraverse(root->rightchild);
		cout << root->data << ' ';
	}
}
int main()
{
	BinaryTreeNode *root = new BinaryTreeNode(1);
	root->leftchild = new BinaryTreeNode(2);
	root->rightchild = new BinaryTreeNode(3);
	root->leftchild->leftchild = new BinaryTreeNode(4);
	root->leftchild->leftchild->rightchild = new BinaryTreeNode(7);
	root->rightchild->leftchild = new BinaryTreeNode(5);
	root->rightchild->rightchild = new BinaryTreeNode(6); 
	root->rightchild->rightchild->leftchild = new BinaryTreeNode(8); 


	vector<int> pre,in,last;
	
    pre.push_back(1);//这棵树的前序遍历
    pre.push_back(2);
    pre.push_back(4);
    pre.push_back(7);
    pre.push_back(3);
    pre.push_back(5);
    pre.push_back(6);
	pre.push_back(8);
	
    in.push_back(4);//这棵树的中序遍历
    in.push_back(7);
    in.push_back(2);
    in.push_back(1);
    in.push_back(5);
    in.push_back(3);
	in.push_back(8);
    in.push_back(6);
	/*
	in.push_back(7);//*这棵树的后序遍历
    in.push_back(4);
    in.push_back(2);
    in.push_back(5);
    in.push_back(8);
    in.push_back(6);
	in.push_back(3);
    in.push_back(1);
	*/
	BinaryTreeNode *newroot1 = PlantTree1(pre,in); //通过前序遍历和中序遍历构建一棵树
	//BinaryTreeNode *newroot2 = PlantTree2(last,in); //通过前序遍历和中序遍历构建一棵树

    cout<<"之前的二叉树先序遍历:";
	PreorderTraverse(root);
    cout<<endl;
    cout<<"之前的二叉树中序遍历:";
	InorderTraverse(root);
    cout<<endl;
    cout<<"之前的二叉树后序遍历:";
	LastOrderTraverse(root);
    cout<<endl;
	cout<<endl;
	
	cout<<"通过前序和中序重建出的二叉树"<<endl;
    cout<<"重建后的二叉树前序遍历:";
	PreorderTraverse(newroot1);
	cout<<endl;
	cout<<"重建后的二叉树中序遍历:";
	InorderTraverse(newroot1);
	cout<<endl;
	cout<<"重建后的二叉树中序遍历:";
	LastOrderTraverse(newroot1);
    cout<<endl;
	cout<<endl;
	
	/*
	cout<<"通过后序和中序重建出的二叉树"<<endl;
    cout<<"重建后的二叉树前序遍历:";
	PreorderTraverse(newroot2);
	cout<<endl;
	cout<<"重建后的二叉树中序遍历:";
	InorderTraverse(newroot2);
	cout<<endl;
	cout<<"重建后的二叉树中序遍历:";
	LastOrderTraverse(newroot2);
    cout<<endl;
	*/
}

 

牛客网上的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> in)
    {
        if(pre.size() == 0 ||in.size() == 0||pre.size() != in.size())
	    {
		    return NULL;  //错误条件
	    }

	    TreeNode *root = new TreeNode(pre[0]); //先序第一个值为根节点
	    int index = 0;
	    vector<int> left_pre,right_pre,left_in,right_in;

	//在中序遍历找到 根节点
	    for(int i = 0; i< (in.size()); i++)
	    {
            if(root->val == in[i])
			    index = i;
	    }

	    for(int i = 0; i < index; i++)
	    {
		    left_pre.push_back(pre[i+1]);		//根节点左子树前序遍历
		    left_in.push_back(in[i]); //根节点左子树中序遍历
	    }

	    for(int j = index+1; j < pre.size(); j++)
	    {
		    right_pre.push_back(pre[j]);
		    right_in.push_back(in[j]);
	    }

	    root->left = reConstructBinaryTree(left_pre,left_in);
	    root->right = reConstructBinaryTree(right_pre,right_in);

	    return root;

    }
};

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值