https://www.luogu.org/problemnew/show/P1030
题目描述
给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度≤8)。
输入输出格式
输入格式:
2行,均为大写字母组成的字符串,表示一棵二叉树的中序与后序排列。
输出格式:
1行,表示一棵二叉树的先序。
输入输出样例
输入样例#1: 复制
BADC
BDCA
输出样例#1: 复制
ABCD
解题思路:
知道后序序列,则后序序列的最后一个为根节点,再在中序序列中找到根节点,左边为左子树,右边为右子树。
假设有中序序列 str1 = DBEAFCG
后序序列 str2 = DEBFGCA,
在str2中找到A为根节点,DBE为左子树, FCG为右子树,
再找DBE的根节点,为B.......一直重复找即可。
代码中l1, r1,是str1中的左界和右界,在str1中找到根节点后,l1到根节点的长度为左子树的长度,
知道长度后可以知道左子树在str2中的位置,递归求解。
直接输出根节点:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#define N 20
char str1[N], str2[N];
int find (char ch)
{
for (int i=0; i<strlen(str1); i++)
{
if(str1[i]==ch)
return i;
}
}
void tree (int l1, int r1, int l2, int r2)
{
int mid = find (str2[r2]);
printf("%c", str2[r2]);
if(l1<mid)
tree(l1, mid-1, l2, l2+mid-1-l1);
if(r1>mid)
tree(mid+1, r1, l2+mid-l1, r2-1);
}
int main()
{
scanf("%s%s", str1, str2);
tree(0, strlen(str1)-1, 0, strlen(str2)-1);
return 0;
}
建树输出:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#define N 20
char str1[N], str2[N];
struct Tree{
char ch;
Tree *l;
Tree *r;
}*root;
int find (char ch)
{
for (int i=0; i<strlen(str1); i++)
{
if(str1[i]==ch)
return i;
}
}
void tree (int l1, int r1, int l2, int r2, Tree *root)
{
int mid;
root->ch = str2[r2];
mid = find(str2[r2]);
if(l1<mid)
{
root->l = (Tree *)malloc(sizeof(Tree));
tree(l1, mid-1, l2, l2+mid-1-l1, root->l);
}
else
root->l=NULL;
if(r1>mid)
{
root->r = (Tree *)malloc(sizeof(Tree));
tree(mid+1, r1, l2+mid-l1, r2-1, root->r);
}
else
root->r=NULL;
return ;
}
void P(Tree *root)
{
printf("%c", root->ch);
if(root->l!=NULL)
{
Tree *p = root->l;
P(p);
}
if(root->r!=NULL)
{
Tree *p = root->r;
P(p);
}
}
int main()
{
scanf("%s%s", str1, str2);
root=(Tree *)malloc(sizeof(Tree));
tree(0, strlen(str1)-1, 0, strlen(str2)-1, root);
P(root);
return 0;
}