【数据结构--二叉树】通过二叉树的中序和前序(或后序)获得后序(或前序)

首先我们都知道,通过一段中序序列和前序序列能够确定一个二叉树,同理中序和后序也能确定(注意必须包括中序)

这边顺便复习一下三者区别:

先序:根,左子树,右子树

中序:左子树,根,右子树

后序:左子树,右子树,根

现在我们需要尝试一下它的实际代码操作是怎样的:

首先这是一个由中序遍历和前序遍历输出后序遍历的代码

#include <iostream>
#include <cmath>
#include <string>
using namespace std;
string pre, in;	//pre表示前序,in表示中序
void work(int al,int ar,int bl,int br) {//分别对应前序的最左边下标,最右边下标,中序的最左边下标,最右边下标
    if (al > ar || bl > br)    return;	//判断递归结束条件
    char root = pre[al];		//前序的首位即是该段树的根
    int k = in.find(root);		//找到根在中序中的下标
    work(al + 1, al + k - bl, bl, k - 1);	//递归左子树
    work(al + k - bl + 1, ar, k + 1, br);	//递归右子树
    cout << root;
}
int main()
{
    cin >> in >> pre;			//先输入中序再输入前序
    int len = pre.length() - 1;		//注意我们这里下标从0开始,所以长度-1
    work(0, len, 0, len);
    return 0;
}

先看主函数,分别输入中序和前序的字符串,随后获取长度,然后调用函数work

接下来重点分析work函数的参数,al表示前序左边界的下标,ar表示前序右边界下标,同理bl,br就是中序下标

work函数的实现原理在注释中写的很清楚,这里简单说一下:

例如我们输入的中序前序分别是:

ABEDFCHG
CBADEFGH 

(下标从0开始)

那么进入函数时我们需要根据前序获得树的根C,然后在中序中找到C对应的下标,得到k=5

然后我们根据这个k值就可以在两个序列中分别截断左子树和右子树,然后将下标递归work函数就可以,最后再输出此时的树根,可以获得后序序列:

AEFDBHGC

这个输出放在两个递归后面,形式其实非常像二叉树的后序输出,一个道理


当然如果你不理解这个work函数里面参数传递的值,这里会特别讲一下:

假如对于上面的输入,我们可以知道第一次进入函数得到root='C',k=5

k=5意味着中序中'C'的左边有5个元素而右边有2个元素

那么接下来我们要递归根为C的左子树和右子树,自然要删除C

那么此时左子树的al=al+1=1(删去第一个元素),ar=al+k-bl=5(注意-bl想要理解最好自己测试一下对于右子树的递归)        bl=bl=0,br=k-1=4(也就是k的左边)

对于右子树al=al+k-bl+1=6(左子树前序的右下标+1 ),ar=ar=7        bl=k+1=6,br=br=7

非常简单,建议自己对于这组输入自己画一下提高理解


  最后这组数据来自于洛谷的题,大家可以自己写一写试试

[USACO3.4] 美国血统 American Heritage - 洛谷


当然上面那个只是中序和前序获得后序,接下来同理给出后序和中序得到前序的函数代码

#include <iostream>
#include <cmath>
#include <string>
using namespace std;
string info, post;
void work(int al,int ar,int bl,int br) {
    if (al > ar || bl > br)    return;
    char root = post[ar];
    int k = info.find(root);
    cout << root;
    work(al, al + k - 1 - bl, bl, k - 1);
    work(al + k - bl, ar - 1, k + 1, br);
}
int main()
{
    cin >> info >> post;
    int len = post.length() - 1; //因为下标从0开始,所以-1
    work(0, len, 0, len);
    cout << endl;
    return 0;
}

这里是先输入中序in,再输入后序post,这里和前面不同点要注意:

root根是后序post的下标ar的位置,也就是post的尾部

然后输出根要放在递归前面,因为先序是先输出根嘛

最后这个函数的参数也有所改变,自己理解一下即可


来自于:

[NOIP2001 普及组] 求先序排列 - 洛谷

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值