重建二叉树

本文介绍如何根据二叉树的前序遍历和中序遍历结果重建二叉树的方法,并提供了一个具体的C++实现示例。

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

根据二叉树的前序遍历和中序遍历的结果,重建这棵树。

分析:前序遍历的每一个节点,都是当前子树的根节点。同时,以对应的节点为边界,就会把中序遍历的结果分为左子树和右子树。

前序:a b d c e f

          “a是根节点

中序:d b a e c f

          “a是根节点,把字符串分成左右两个子树

       "a"是前序遍历节点中的第一个元素,可以看出,它把中序遍历的结果分成"db"和'ecf"这两部分。

       如果能够找到前序遍历中对应的左子树和右子树,就可以把"a"作为当前的根节点,然后依次递归下去,这样就能够依次恢复左子树和右子树的遍历结果。

上代码:

#include <iostream>
using namespace std;


#define TREELEN	6

struct	NODE
{
	NODE* pLeft;
	NODE* pRight;
	char chValue;
};

void rebuild(char* pPreOrder, char* pInOrder, int nTreeLen, NODE** pRoot)
{
	//检查边界条件
	if (pPreOrder == NULL || pInOrder == NULL)
	{
		return;
	}
	//获取前序遍历的第一个结点
	NODE* pTemp = new NODE;
	pTemp->chValue = *pPreOrder;
	pTemp->pLeft = NULL;
	pTemp->pRight = NULL;

	//如果结点为空,把当前结点复制到根节点
	if (*pRoot == NULL)
	{
		*pRoot = pTemp;
	}

	//如果当前长度为1,那么已经是最后一个节点
	if (nTreeLen == 1)
	{
		return;
	}
	
	//寻找子树长度
	char* pOrgInorder = pInOrder;
	char* pLeftEnd = pInOrder;
	int nTempLen = 0;

	//寻找左子树的结尾
	if (*pPreOrder != *pLeftEnd)
	{
		if (pPreOrder == NULL || pLeftEnd == NULL)
		{
			return;
		}
		nTempLen++;
		
		//记录临时长度,以免溢出
		if (nTempLen > nTreeLen)
		{
			exit(-1);
		}
		pLeftEnd++;
	}

	//寻找左子树长度
	int pLeftLen = 0;
	pLeftLen = (int)(pLeftEnd - pOrgInorder);
	
	//寻找右子数长度
	int pRightLen = 0;
	pRightLen = (int)(nTreeLen - pLeftLen - 1);
	
	//重建左子树
	if (pLeftLen > 0)
	{
		rebuild(pPreOrder+1, pInOrder, pLeftLen, &((*pRoot)->pLeft));
	}

	//重建右子树
	if (pRightLen > 0)
	{
		rebuild(pPreOrder+pLeftLen+1, pInOrder+pLeftLen+1, pRightLen, &((*pRoot)->pRight));
	}
}

int main()
{
	char szPreOrder[TREELEN] = {'a', 'b', 'd', 'c', 'e', 'f'};
	char szInOrder[TREELEN] = {'d', 'b', 'a', 'e', 'c', 'f'};

	NODE* pRoot = NULL;
	rebuild(szPreOrder, szInOrder, TREELEN, &pRoot);
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值