#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;
}
16浙大模拟赛 上帝的视角(树的问题)
最新推荐文章于 2019-03-10 22:26:04 发布