1078 二叉树的遍历

题目描述: 
二叉树的前序、中序、后序遍历的定义:
 前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
 给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍历与中序遍历能够唯一确定后序遍历)。
输入: 
两个字符串,其长度n均小于等于26。
 第一行为前序遍历,第二行为中序遍历。
 二叉树中的结点名称以大写字母表示:A,B,C....最多26个结点。
输出: 
输入样例可能有多组,对于每组测试样例,
 输出一行,为后序遍历的字符串。

样例输入:

ABC

BAC
FDXEAG
XDEFAG

样例输出: 

BCA

XEDGAF

算法实现;

/*遍历二叉树 */
//由二叉树前序和中序序列得出后序遍历序列
//递归思想 这个算法真心不错!
#include<stdio.h>
#include<string.h>
void GetPost(char pre[],char in[],char post[],int len){//这三个数组表示当前的起始地址
	int i;						//len表示当前子树结点的个数
	if(len<=0)
		return ;
	post[len-1]=pre[0];//当前第一个元素即为父节点 放在数组最后
	for(i=0;i<=len;i++){
		if(in[i]==pre[0]){
			break;
		}
	}
	GetPost(pre+1,in,post,i);
	GetPost(pre+i+1,in+i+1,post+i,len-i-1);

}

int main(){	
	char pre[30],in[30],post[30];//存储三种遍历序列
	int len;
	freopen("test.txt","r",stdin);
	while(scanf("%s%s",pre,in)!=EOF){
		len=strlen(pre);
		GetPost(pre,in,post,len);
		post[len]=0;//!!
		printf("%s\n",post);
	}
	fclose(stdin);
	return 0;
}
特别注意:

1.在刚开始接触树的题目时,首先会想到建立一颗完整的树结构,然后对其进行遍历,插入等等,但是学习过别人的算法之后发现,完全不用,只需根据二叉树的思想,就可以用数组直接解决;

2.本题中的递归算法很好,传递地址,而非自己的想法,传递数组边界参数,每一次递归,都看做是一个前序和中序序列,然后同样的解决方法求得;

3.同样的题目还有1113 求完全二叉树某一子树的结点总数,本题也可以用递归算法,但是结果会超时,因此又要求助高人了,直接用一个循环就实现了,题目和实现如下:

题目描述: 
 如上所示,由正整数1,2,3……组成了一颗特殊二叉树。我们已知这个二叉树的最后一个结点是n。现在的问题是,结点m所在的子树中一共包括多少个结点。
比如,n = 12,m = 3那么上图中的结点13,14,15以及后面的结点都是不存在的,结点m所在子树中包括的结点有3,6,7,12,因此结点m的所在子树中共有4个结点。
输入: 
    输入数据包括多行,每行给出一组测试数据,包括两个整数m,n (1 <= m <= n <= 1000000000)。最后一组测试数据中包括两个0,表示输入的结束,这组数据不用处理。 
输出: 
    对于每一组测试数据,输出一行,该行包含一个整数,给出结点m所在子树中包括的结点的数目。
样例输入: 

3 12
0 0
样例输出: 

4

算法实现

/* 二叉树*/
//求完全二叉树某一子树的结点个数
//非递归算法 采用递归超时
#include<stdio.h>
int main(){
	int n,m,left,right,cnt,num;//cnt 每层的节点个数 num所求的结点总数
	//freopen("test.txt","r",stdin);
	while(scanf("%d%d",&m,&n)!=EOF){
		if(m==0&&n==0) break;
		num=cnt=1;
		left=2*m;
		right=2*m+1;
		while(right<=n){
			cnt=cnt*2;//该子树本层的结点个数
			num+=cnt;//本层均包含在本子树中
			left=2*left;
			right=2*right+1;
		}
		if(left<=n){
			num+=n-left+1;
		}
		printf("%d\n",num);
	}
	//fclose(stdin);
	return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值