一、根据后序和中序求先序序列
后中->先例题:P1030 [NOIP2001 普及组] 求先序排列
1.题目分析——两个子问题
(1)根据后序遍历和中序遍历创建对应的二叉树
由于后序遍历的最后一个结点必然是根节点,可以在中序遍历中找到这个根节点的位置p(假设下标从0开始),于是可以知道,在中序序列中根节点左边的所有节点一定属于左子树,右边的所有节点一定属于右子树,根据这个判断,可以知道左右子树分别有p和(n-p-1)个结点,而它们必然对应原序列中从第0个元素开头的所有结点和第p个元素开头的所有结点。于是可以将一段序列分为左子树和右子树,从而递归地去解决这个问题,直到生成整个二叉树。
(2)根据生成的二叉树求出其后序遍历序列
略
2.核心函数
BiTree BuildTree(char a[], char b[], int n)
{
BiTree Root;
int p;
if (n == 0)return NULL;
Root = (BiTree)malloc(sizeof(struct BiTNode));
Root->data = b[n - 1];
Root->lchild = Root->rchild = NULL;
for (p = 0; p < n; p++)
if (a[p] == b[n - 1])break;
Root->lchild = BuildTree(a, b, p);
Root->rchild = BuildTree(a + p + 1, b + p, n - p - 1);
return Root;
}
3.总代码及运行结果
(1)总代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char TElemType;
char a[10], b[10];
typedef struct BiTNode {
TElemType data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
BiTree BuildTree(char a[], char b[], int n)
{
BiTree Root;
int p;
if (n == 0)return NULL;
Root = (BiTree)malloc(sizeof(struct BiTNode));
Root->data = b[n - 1];
Root->lchild = Root->rchild = NULL;
for (p = 0; p < n; p++)
if (a[p] == b[n - 1])break;
Root->lchild = BuildTree(a, b, p);
Root->rchild = BuildTree(a + p + 1, b + p, n - p - 1);
return Root;
}
void PreTraverse(BiTree Root)
{
if (Root == NULL)return;
putchar(Root->data);
PreTraverse(Root->lchild);
PreTraverse(Root->rchild);
}
int main()
{
BiTree Root = NULL;
scanf("%s%s", a, b);
int n = strlen(a);
Root = BuildTree(a, b, n);
PreTraverse(Root);
return 0;
}
(2)运行结果
二、根据先序和中序求后序序列
先中->后例题:P1827 [USACO3.4] 美国血统 American Heritage
思路与上一题基本一致这里不再赘述,直接给出代码
总代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
typedef char TElemType;
char a[10], b[10];
typedef struct BiTNode {
TElemType data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;
BiTree BuildTree(char a[], char b[], int n)
{
BiTree Root;
int p;
if (n == 0)return NULL;
Root = (BiTree)malloc(sizeof(struct BiTNode));
Root->data = b[0];
Root->lchild = Root->rchild = NULL;
for (p = 0; p < n; p++)
if (a[p] == b[0])break;
Root->lchild = BuildTree(a, b + 1, p);
Root->rchild = BuildTree(a + p + 1, b + p + 1, n - p - 1);
return Root;
}
void AfterTraverse(BiTree Root)
{
if (Root == NULL)return;
AfterTraverse(Root->lchild);
AfterTraverse(Root->rchild);
putchar(Root->data);
}
int main()
{
BiTree Root = NULL;
scanf("%s%s", a, b);
int n = strlen(a);
Root = BuildTree(a, b, n);
AfterTraverse(Root);
return 0;
}
运行结果:
三、根据层序遍历和中序遍历推出另外两种遍历
层中->先后例题:二叉树遍历
1.题目分析
暂时还没有搞懂:AcWing 1259. 二叉树遍历 - AcWing