每日一题(29) - 重建二叉树

本文介绍了一种根据给定的二叉树的前序遍历和中序遍历序列来重建该二叉树的方法。通过递归地寻找根节点,并根据中序遍历确定左右子树范围,逐步构建出完整的二叉树结构。

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

题目来自剑指Offer和编程之美

题目:


对应的图:


思路:

根据前序遍历找出根,根据中序遍历找出左右子树区间。边缩小区间边生成树结点,直到树建立完成

注意:

在两个数组中在计算左右子树的区间时,需要通过记录子树中结点的个数获得。

代码:

BinaryTreeNode* Construct(int* pPreOrder,int* pInorder,int nLen)
{
	assert(pPreOrder && pInorder && nLen > 0);
	return Construct(pPreOrder,0,nLen - 1,pInorder,0,nLen - 1);
}

BinaryTreeNode* Construct(int* pPreOrder,int nPreStart,int nPreEnd,int* pInorder,int nInStart,int nInEnd)
{
	//出口
	if (nInStart > nInEnd)
	{
		return NULL;
	}
	//根据先序序列,找到根结点
	int nRootValue = pPreOrder[nPreStart];
	//在中序序列中找到根结点
	int nCount = 0;
	int nCur = 0;
	for (nCur = nInStart;nCur <= nInEnd;nCur++)
	{
		if (nRootValue != pInorder[nCur])
		{
			nCount++;
		}
		else
		{
			break;
		}
	}
	assert(nCur >= nInStart && nCur <= nInEnd);
	//创建结点
	BinaryTreeNode* pNode = new BinaryTreeNode;
	pNode->m_nValue = nRootValue;	
	//根据中序序列,划分两个序列,递归处理。
	pNode->m_pLeft = Construct(pPreOrder,nPreStart + 1,nPreStart + nCount,pInorder,nInStart,nInStart + nCount - 1);
	pNode->m_pRight = Construct(pPreOrder,nPreStart + nCount + 1,nPreEnd,pInorder,nInStart + nCount + 1,nInEnd);
	return pNode;
}
测试代码:

#include <iostream>
#include <assert.h>
using namespace std;

struct BinaryTreeNode
{
	int m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};

BinaryTreeNode* Construct(int* pPreOrder,int nPreStart,int nPreEnd,int* pInorder,int nInStart,int nInEnd)
{
	//出口
	if (nInStart > nInEnd)
	{
		return NULL;
	}
	//根据先序序列,找到根结点
	int nRootValue = pPreOrder[nPreStart];
	//在中序序列中找到根结点
	int nCount = 0;
	int nCur = 0;
	for (nCur = nInStart;nCur <= nInEnd;nCur++)
	{
		if (nRootValue != pInorder[nCur])
		{
			nCount++;
		}
		else
		{
			break;
		}
	}
	assert(nCur >= nInStart && nCur <= nInEnd);
	//创建结点
	BinaryTreeNode* pNode = new BinaryTreeNode;
	pNode->m_nValue = nRootValue;	
	//根据中序序列,划分两个序列,递归处理。
	pNode->m_pLeft = Construct(pPreOrder,nPreStart + 1,nPreStart + nCount,pInorder,nInStart,nInStart + nCount - 1);
	pNode->m_pRight = Construct(pPreOrder,nPreStart + nCount + 1,nPreEnd,pInorder,nInStart + nCount + 1,nInEnd);
	return pNode;
}

BinaryTreeNode* Construct(int* pPreOrder,int* pInorder,int nLen)
{
	assert(pPreOrder && pInorder && nLen > 0);
	return Construct(pPreOrder,0,nLen - 1,pInorder,0,nLen - 1);
}

void PreOrderT(BinaryTreeNode* pNode)
{
	if (pNode)
	{
		cout<<pNode->m_nValue<<" ";
		PreOrderT(pNode->m_pLeft);
		PreOrderT(pNode->m_pRight);
	}
}

void InOrderT(BinaryTreeNode* pNode)
{
	if (pNode)
	{
		InOrderT(pNode->m_pLeft);
		cout<<pNode->m_nValue<<" ";
		InOrderT(pNode->m_pRight);
	}
}

int main()
{
	//正常二叉树
	int PreOrder[8] = {1,2,4,7,3,5,6,8};
	int InOrder[8] = {4,7,2,1,5,3,8,6};
	BinaryTreeNode* pRoot = Construct(PreOrder,InOrder,8);
	
	//右单支
	/*int PreOrder[6] = {1,2,3,4,5,6};
	int InOrder[6] = {1,2,3,4,5,6};
	BinaryTreeNode* pRoot = Construct(PreOrder,InOrder,6);*/
	
	//左单支
	/*int PreOrder[6] = {1,2,3,4,5,6};
	int InOrder[6] = {6,5,4,3,2,1};
	BinaryTreeNode* pRoot = Construct(PreOrder,InOrder,6);*/
	
	cout<<"PreOrder: ";
	PreOrderT(pRoot);
	cout<<endl<<"InOrder: ";
	InOrderT(pRoot);
	cout<<endl;
	system("pause");
	return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值