给出前序与中序 序列 重建二叉树

本文介绍了如何通过给定的前序和中序序列重建二叉树。首先,找到前序序列中的根节点,然后利用中序序列划分左子树和右子树的序列。通过递归方式,分别构建根节点的左子树和右子树,最终实现整个二叉树的重建。以给定的示例序列`preorderSequence`和`InorderSequence`为例,详细阐述了重建过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试题: 给出一个前序序列 和 中序序列 重建出这颗二叉树


思路:  通过前序序列, 我们可以找到这颗二叉树的 根, 找到根后 通过中序遍历序列, 我们可以找出 这个根的 左子树 和 右子树 序列。


有了这层思路, 我们就可以 通过递归的方式分别去 构建 根 根的左子树,  根的右子树


给出:

int preorderSequence[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
int InorderSequence[] = { 4, 7, 2, 1, 5, 3, 8, 6 };


我们根据, 前序 得知这棵树的 根是1  通过中序 得知  4721 是它左子树序列, 5386是它右子树序列


然后 递归   通过前序(根 左右)   我们得知 根的左子树, 的根节点为2 , 接着重复前面思路即可。  

给出代码, 会比较好理解:

#include <iostream>
#include <windows.h>
using namespace std;
//注意,如果不是在类里面,如果是用面向过程思想写代码 -->> 函数需要先声明,再使用(即顺序:  声明->定义->main( ))!
//而且注意, 函数声明要放在 结点 定义之下


struct BinaryTreeNode
{
	int _data;
	BinaryTreeNode* _left;
	BinaryTreeNode* _right;

	BinaryTreeNode( int data, BinaryTreeNode* left = NULL, BinaryTreeNode* right = NULL )
		: _data( data )
		, _left( left )
		, _right( right )
	{}
};


BinaryTreeNode* ConstructCore( int* startPreorder, int* endPreorder, int* startInorder, int* endInorder );


BinaryTreeNode* Construct( int* preorder, int* inorder, int length )
{
	if ( NULL == preorder || NULL == inorder || length <= 0 )
		return NULL;

	return ConstructCore( preorder, preorder+length-1, inorder, inorder+length-1 );
}

BinaryTreeNode* ConstructCore( int* startPreorder, int* endPreorder
							  , int* startInorder, int* endInorder )
{
	int rootValue = startPreorder[0];
	
	BinaryTreeNode* root = new BinaryTreeNode( rootValue );

	//如果只有一个数据,就返回这个结点
	if ( startPreorder == endPreorder )
	{
		if ( startInorder == endInorder && *startInorder == *startPreorder )
			return root;
		else
			throw std::exception( "输入数据有误" );
	}

	int* rootInorder = startInorder;

	//中序遍历中找到根结点的值
	while ( rootInorder <= endInorder && rootValue != *rootInorder )//常量写在 左边 
		++rootInorder;

	if ( rootInorder > endInorder )
		throw std::exception( "输入数据有误." );

	int leftLength = rootInorder - startInorder;
	int* leftPreorderEnd = startPreorder + leftLength;

	//构建 root 的左子树
	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;
}

//中序遍历打印
void PrintBinaryTree( BinaryTreeNode* root )
{
	if ( NULL == root )
		return;

	PrintBinaryTree( root->_left );

	cout << root->_data << " ";

	PrintBinaryTree( root->_right );
}

void TestConstructBinaryTree( )
{
	int preorderSequence[] = { 1, 2, 4, 7, 3, 5, 6, 8 };
	int InorderSequence[] = { 4, 7, 2, 1, 5, 3, 8, 6 };

	BinaryTreeNode* root = Construct( preorderSequence, InorderSequence, sizeof(InorderSequence)/sizeof(InorderSequence[0]) );

	PrintBinaryTree( root );
	cout << endl;
}

int main( )
{
	TestConstructBinaryTree( );

	system( "pause" );
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值