【PTA】还原二叉树 && 根据后序和中序遍历输出先序遍历&&树的遍历

43 篇文章 5 订阅
38 篇文章 4 订阅

还原二叉树

给定一棵二叉树的先序遍历序列和中序遍历序列,要求计算该二叉树的高度。

输入格式:
输入首先给出正整数N(≤50),为树中结点总数。下面两行先后给出先序和中序遍历序列,均是长度为N的不包含重复英文字母(区别大小写)的字符串。

输出格式:
输出为一个整数,即该二叉树的高度。

输入样例:

9
ABDFGHIEC
FDHGIBEAC

输出样例:

5
#include<stdio.h>
#include<stdlib.h>
typedef struct snode * bintree;
struct snode{
	bintree left,right;
};	
int n;
char a[50],b[50];
bintree fact(int pmin,int min,int max)
{
	bintree bt=(bintree)malloc(sizeof(struct snode));
	bt->left=bt->right=NULL;
	for(int i=min;i<=max;i++){
		if(a[pmin]==b[i]){
			if(i!=min) bt->left=fact(pmin+1,min,i-1);
			if(i!=max) bt->right=fact(pmin+i-min+1,i+1,max);
			/*pmin+i-min+1:pmin是先序排列中间节点,i-min就是左边子节点的长度,+1就是右节点的位置了.
			先序排列在创建右节点时 ,右节点右边的位置可以不写*/ 
			break;
		}
	} 
	return bt;
}
int high(bintree bt)
{
	int m,a,b;
	if(bt){
		a=high(bt->left);
		b=high(bt->right);
		m=a>b?a:b; 
		return m+1;
	}
	else return 0;	
}
int main()
{

	scanf("%d %s %s",&n,&a,&b);
//	scanf("%d",&n);getchar();	gets(a);gets(b);
//	这样写是错的。。。我也不知道为什么 
	
	bintree bt=fact(0,0,n-1);
	printf("%d",high(bt));
	return 0;
}

根据后序和中序遍历输出先序遍历

戳我点开题

本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。

输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。

输出格式:
在一行中输出Preorder:以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

Preorder: 4 1 3 2 6 5 7
#include<stdio.h>
#include<stdlib.h>
char a[50],b[50];
typedef struct snode * bintree;
struct snode{
	int data;
	bintree left,right;
};
bintree creat(int pmax,int min,int max){
	bintree bt=(bintree)malloc(sizeof(struct snode));
	bt->data=a[pmax];
	bt->left=bt->right=NULL;
	for(int i=min;i<=max;i++){
		if(a[pmax]==b[i]){
			if(i!=min) bt->left=creat(pmax-(max-i)-1,min,i-1);
			//pmax可以说是一个树的节点长度,max-i就是右子树的长度,相减再-1就是左子树的根节点 
			if(i!=max) bt->right=creat(pmax-1,i+1,max);
			break;
		}
	}
	return bt;
}
void xianxun(bintree bt){
	if(bt){
		printf(" %d",bt->data);
		xianxun(bt->left);
		xianxun(bt->right);
	}
}
int main()
{
	int n,i;
	scanf("%d",&n);
	for(i=0;i<n;i++) scanf("%d",&a[i]);
	for(i=0;i<n;i++) scanf("%d",&b[i]);
	printf("Preorder:");
	xianxun(creat(n-1,0,n-1));
	return 0;
}

树的遍历

戳我点开题
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。

输出格式:
在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

4 1 6 3 5 7 2
#include<stdio.h>
#include<stdlib.h>
typedef struct snode * bintree;
struct snode{
	int data;
	bintree left,right;
};
typedef struct node * queue;
struct node{
	bintree *data;
	int front,roar;
};
int a[50],b[50];
bintree creat_bintree(int pmax,int min,int max);
void print(bintree bt);
int main()
{
	int n,i;
	bintree bt=(bintree)malloc(sizeof(struct snode));
	scanf("%d",&n);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);
	for(i=0;i<n;i++)
		scanf("%d",&b[i]);
	bt=creat_bintree(n-1,0,n-1);
	print(bt);
	return 0;
}
bintree creat_bintree(int pmax,int min,int max)
{
	bintree bt=(bintree)malloc(sizeof(struct snode));
	bt->data=a[pmax];
	bt->left=bt->right=NULL;
	for(int i=min;i<=max;i++){
		if(a[pmax]==b[i]){
			if(i!=min) bt->left=creat_bintree(pmax-(max-i)-1,min,i-1);
			if(i!=max) bt->right=creat_bintree(pmax-1,i+1,max);
		}
	}
	return bt;
}
void print(bintree bt)
{
	if(!bt) return;
	int f=0;
	bintree t;
	queue s=(queue)malloc(sizeof(struct node));
	s->data=(bintree *)malloc(sizeof(bintree)*100);
	s->front=s->roar=0;
	s->data[++(s->roar)]=bt;
	while(s->front!=s->roar){
		if(f!=0){
			printf(" ");
		}
		else f=1;
		t=s->data[++(s->front)];
		printf("%d",t->data);
		if(t->left) 
			s->data[++(s->roar)]=t->left;
		if(t->right) 
			s->data[++(s->roar)]=t->right;
	}
}

L2-011 玩转二叉树 (25分)

L2-011 玩转二叉树 (25分)
给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。

输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其中序遍历序列。第三行给出其前序遍历序列。数字间以空格分隔。

输出格式:
在一行中输出该树反转后的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

输入样例:

7
1 2 3 4 5 6 7
4 1 3 2 6 5 7

输出样例:

4 6 1 7 5 3 2
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int T,n,m,ans;
int a[N],b[N];
struct node{
	int lift,right;
}t[N];
int buildTree(int pos,int l,int r){
	for(int i=l;i<=r;i++){
		if(a[i]==b[pos]){
			if(i!=l)t[b[pos]].lift=buildTree(pos+1,l,i-1);
			if(i!=r)t[b[pos]].right=buildTree(pos+i-l+1,i+1,r);
			break;
		}
	}
	return b[pos];
}
int main()
{
	int i,id,x,y,z,L;
	scanf("%d",&n);
	for(i=0;i<n;i++) scanf("%d",&a[i]);
	for(i=0;i<n;i++) scanf("%d",&b[i]);
	int root=buildTree(0,0,n-1);
	queue<int>q;
	q.push(root);
	while(!q.empty()){
		int f=q.front();
		if(f!=root) printf(" ");
		printf("%d",f);
		q.pop();
		if(t[f].right) q.push(t[f].right);
		if(t[f].lift) q.push(t[f].lift);
	}
	return 0;
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值