16浙大模拟赛 上帝的视角(树的问题)

题目网址

#include <stdio.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <queue>
using namespace std;
const int maxn = 31;
int n,n1,n2;//n用来记录节点个数,n1,n2用来控制先序遍历和后序遍历时的输出格式,最后一个元素不能有空格
int level[maxn], in[maxn];//level数组存储用户输入的层次遍历,in数组用于存储用户输入的中序遍历
typedef struct node {
		int value;
		node *left, *right;
		int level;//为每个节点增加一个层次属性,标志此节点位于树的第几层,最大值为树的高度
	}node;
node* creatTree(int rootPos,int inL,int inR)
{
	set<int> se1;//set容器具有自动排序为递增的功能,se1用于存储左子树的节点在层次序列中的下标位置,se1的第一个数便是此节点的左孩子节点
	set<int> se2;//se1的第一个数便是此节点的左孩子节点在层次遍历中的数组下标
	if (rootPos<0)//递归的边界条件
		return NULL;
	node *root = new node;
	root->value = level[rootPos];
	int k;
	for (k = 0; k < n; k++)//找到此节点在中序遍历中的位置k
	{
		if (in[k] == level[rootPos])
			break;
	}//k是中序遍历中根节点的位置
	int numleft = k - inL;//左子树节点个数
	for (int i = k - 1; i >= inL; i--)
	{
		for (int j = 0; j < n; j++)
		{
			if (level[j] == in[i])
			{
				se1.insert(j);
				break;
			}		
		}
	}
	for (int i = k + 1; i <=inR; i++)
	{
		for (int j = 0; j < n; j++)
		{
			if (level[j] == in[i])
				se2.insert(j);
		}
	}
	int Lrootpos, Rrootpos;
	if (se1.size() > 0)
		Lrootpos = *se1.begin();
	else
		Lrootpos = -1;
	if (se2.size()>0)
		Rrootpos = *se2.begin();
	else
		Rrootpos = -1;

	root->left = creatTree(Lrootpos, inL, k-1);
	root->right = creatTree(Rrootpos, k+1, inR);
	return root;

}
void preOrder(node *root) 
{
	if (root == NULL)
		return;
	else
	{
		if (--n2>0)
			printf("%d ", root->value);
		else
			printf("%d\n", root->value);
		preOrder(root->left);
		preOrder(root->right);
	}
}
void postOrder(node *root)
{
	if (root == NULL)
		return;
	else
	{
		postOrder(root->left);
		postOrder(root->right);
		if (--n1>0)
			printf("%d ", root->value);
		else
			printf("%d\n", root->value);
	}
}
void levelOrder(node *root)
{
	queue< node* > q;
	q.push(root);
	root->level = 1;
	while (!q.empty())
	{
		node *now = q.front();
		q.pop();
		if (now->left != NULL)
		{
			q.push(now->left);
			now->left->level = now->level + 1;
		}
			
		if (now->right != NULL)
		{
			q.push(now->right);
			now->right->level = now->level + 1;
		}
		if(q.empty())
			printf("%d\n", now->level);
	}
	
}
int countRightUptoLeftDown(node *root)
{
	//int num=1;
	if (root== NULL)
		return 0;
	else 
	{
		return max(countRightUptoLeftDown(root->right)+1, countRightUptoLeftDown(root->left));
	}
}
int countUptoDownL(node *root)
{
	if (root == NULL)
		return 0;
	else
		return max(countUptoDownL(root->left) + 1, countUptoDownL(root->right) - 1);
}
int countUptoDownR(node *root)
{
	if (root == NULL)
		return 0;
	else
		return max(countUptoDownR(root->right) + 1, countUptoDownR(root->left) - 1);
}
int main()
{
	
	while (scanf("%d", &n) != EOF)
	{
		for (int i = 0; i < n; i++)
			scanf("%d", &level[i]);
		for (int i = 0; i < n; i++)
			scanf("%d", &in[i]);

		node *root = creatTree(0, 0, n - 1);
		n1 = n2 = n;
		preOrder(root);
		postOrder(root);
		levelOrder(root);
		printf("%d\n",countRightUptoLeftDown(root));
		printf("%d\n",countUptoDownL(root)+ countUptoDownR(root)-1);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值