先序遍历+中序遍历求二叉树

二叉树的遍历分为前序遍历、中序遍历、后序遍历。先来看一下三种遍历的不同

1前序遍历

(1)访问根节点

(2)前序遍历左子树

(3)前序遍历右子树

2中序遍历

(1)中序遍历左子树

(2)访问根节点

(3)中序遍历右子树

3后序遍历

(1)后序遍历左子树

(2)后续遍历右子树

(3)访问根节点

前序遍历+中序遍历可以求出二叉树的结构;同理后续遍历+中序遍历也可以求出二叉树的结构。但是前序遍历+后续遍历不能求出二叉树的结构。下面以前序遍历+中序遍历来说明一下:

中序遍历的顺序得知,根结点把左右子树分来了,而通过前序遍历有可以得到根结点,这样就可以找到根结点和左右子树的结点,再递归解决左右子树就可以构建二叉树了。


上图中二叉树先序遍历为:ABCDEF

中序遍历为:CBDAEF

假如我们不知道二叉树的结构,通过第一步,我们可以得到

1根结点为A

2左子树结点,左子树先序遍历为BCD,中序遍历为CBD

3右子树结点,右子树先序遍历为EF,中序遍历为EF

如下图


分为两个子问题

(1)左子树问题:先序遍历为BCD,后续遍历为CBD,求左子树

(2)右子树问题:先序遍历为EF,后续遍历为EF,求右子树

递归解决即可。

那为什么先序遍历+后续遍历不能构建出二叉树呢?

很显然,先序遍历+后续遍历只能找到根节点,并不能把左子树和右子树区分开来,所以无法构建二叉树。


测试代码:

#include<iostream>
using namespace std;
class Node{
public:
	Node(char c):data(c),left(NULL),right(NULL){}
	char data;
	Node *left;
	Node *right;
};
//根据前序遍历+中序遍历,,返回根结点
//PreOrder前序遍历结果
//Inorder中序遍历结果
//length树节点个数
Node *MakeBinTree(char *PreOrder, char *InOrder, int length)
{
	if(length<=0)
		return NULL;
	Node *T;//根结点
	int t;//根结点在中序遍历中的位置
	for(t=0;PreOrder[0]!=InOrder[t];t++);//找到根几点在中序遍历中的位置
	T=new Node(PreOrder[0]);
	//递归解决左子树
	T->left=MakeBinTree(PreOrder+1,InOrder,t);//左子树长度为t,不是t-1,因为下标从0开始
	//递归解决右子树
	T->right=MakeBinTree(PreOrder+t+1,InOrder+t+1,length-t-1);
	return T;

}
//后续遍历输出结点信息
void LastOrder(Node *T)
{
	if(T==NULL)
		return ;
	LastOrder(T->left);
	LastOrder(T->right);
	cout<<T->data<<",";
}
int main()
{
	char *PreOrder="ABCDEF";
	char *InOrder="CBDAEF";
	//后续遍历一下,构建二叉树是否正确
	Node *T=MakeBinTree(PreOrder,InOrder,6);
	LastOrder(T);
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值