第八章:二叉树三种遍历以及有二求一

数组实现二叉树遍历以及有二求一

一、首先,我们先上二叉树的三种遍历-----先序遍历,中序遍历,后序遍历

先序遍历:--------父节点,左儿子,右儿子
简化来说:根节点先输出,然后输出左儿子,左儿子有自己的左儿子就输出···依次,直到后面的节点没有左儿子就输出其右儿子,之后和左儿子输出情况一样。

int a[10000];
void per(int root)//root从1开始
{
	if(a[root]==0) 
		return ;
	if(a[root*2]==0&&a[root*2+1]==0) 
		return ;
	printf("%d ",a[root]);
	per(root*2);
	per(root*2+1);
}

特点:
1.第一个数是整个数的根节点,且先是左子树(以整个根的根节点来看),然后是右子树,得到先序遍历的数组,可以确定整个数的根。

中序遍历---------左儿子,父节点,右儿子
简化来说:
先扫遍(递归)所有的左儿子,从最后开始输出左儿子,期间,作为左儿子的根也被输出了,所以不用思索根的输出情况,之后再扫遍所有右儿子,从最后开始输出右儿子。

int a[10000];
void mid(int root)
{
	if(a[root]==0)
		return ;
	if(a[root*2]==0&&a[root*2+1]==0)
		return ;
	mid(root*2);
	printf("%d ",a[root]);
	mid(root*2+1);
}

特点:
1.根节点的左边是其左子树所有成员,根节点右边,是其右子树所有成员。得到中序遍历,可以确定成员的大体位置(是左?是右?)

后序遍历---------左儿子,右儿子,父节点
简化来说:
先扫遍左儿子,再扫遍右儿子,最后输出父节点。

int a[100000];
void end(int root)
{
	if(a[root]==0)
		return ;
	if(a[root*2]==0&&a[root*2+1]==0)
		return ;
	end(root*2);
	end(root*2+1);
	printf("%d ");
}

特点:
1.最后一个数是整个树的根节点,从后往前,先是右子树,再是左子树。
得到后序遍历的数组,可以确定整个数的根。

二、接下来说一下有二求一

已知中序遍历和后序遍历 -------得到先序遍历

重点是抓住中序遍历和后序遍历的特点,先找根,再找左右儿子----具体的代码中说明。

int tree[10000];//重构树
int behind[10000];//已知的后序遍历顺序
int mid[100000];//已知的中序遍历顺序
void buildtree(int root,int l,int r,int t)
//root是根节点下标根据后序遍历得到
//t是重构树的下标
{
	if(l>=r) return ;
	int flag;
	for(int i=l; i<=r; i++){
		if(behind[root]==mid[i]){//找到根节点在中序遍历中的位置,这样好找他的左右儿子
			flag=i;
		}
	}
	tree[t]=mid[flag];
	buildtree(root+flag-r-1,l,flag-1,t*2);//先创建左子树----中序遍历左边左子树。
	buildtree(root-1,flag+1,r,t*2+1);
}

已知先序遍历和中序遍历-------得到后序遍历

重点也是抓住特点,方法和上一个基本相同。

int tree[10000];//重构树
int front[10000];//已知的先序遍历顺序
int mid[100000];//已知的中序遍历顺序
void buildtree(int root,int l,int r,int t)
//root是根节点下标根据先序遍历得到
//t是重构树的下标
{
	if(l>=r) return ;
	int flag;
	for(int i=l; i<=r; i++){
		if(front[root]==mid[i]){//找到根节点在中序遍历中的位置,这样好找他的左右儿子
			flag=i;
		}
	}
	tree[t]=mid[flag];
	buildtree(root+1,l,flag-1,t*2);//先创建左子树----中序遍历左边左子树。
	buildtree(root+flag-l+1,flag+1,r,t*2+1);
}

由于还是小白,暂时会的就这么多---------以后再补充吧。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值