pat甲级1119 Pre- and Post-order Traversals

pat甲级1119 Pre- and Post-order Traversals

note:是否有唯一二叉树,关键在于看非叶节点中是否存在只有一个子树的根节点,若有,则二叉树不唯一,因为无法确定该子树是左子树还是右子树。题目中说二叉树不唯一时,输出其中一种可能的中序序列即可,因此可以将唯一的子树看作左子树,也可以看作右子树,我的做法是看作左子树。

中序遍历方法:首先要确定根节点和子树结点。根节点是先序序列的队首数字也是后序序列的队尾数字。若根节点为非叶子节点,则左子树必然存在,且左子树根节点为先序序列中根节点的下一个数;若先序序列中除根节点外的其他节点均在左子树中,则无右子树,反之则有右子树。然后按照左-中-右的方法递归即可。

采用顺序存储(数组或向量),由于不管先序还是后序序列,任意一棵子树的序列均为连续序列,故确定一棵子树有两种方法:第一是取序列的首尾地址(我用下标代替),第二种是取首地址或尾地址,再取序列长度。经过比较,第二种方法较简单清晰。
好了,废话不多说,上代码:

#include <iostream>
#include <vector>
using namespace std;
vector<int> pre,in,post;
bool flag=true;
void inorder(int preRoot,int num,int postRoot)
{
    int i=0;//统计右子树结点个数
    if(num>1)//若有左子树,隐含i<num-1
    {
        while(post[postRoot-i-1]!=pre[preRoot+1]) ++i;//右子树结点个数
        if(!i) flag=false;//无右子树,标记;
        inorder(preRoot+1,num-1-i,postRoot-i-1);//左子树递归
    }
    in.push_back(pre[preRoot]);
    if(i) inorder(preRoot+num-i,i,postRoot-1);//若有右子树,递归
}
int main()
{
    int n;
    cin>>n;
    pre.resize(n),post.resize(n);
    for(int i=0;i<n;++i) cin>>pre[i];
    for(int i=0;i<n;++i) cin>>post[i];
    inorder(0,n,n-1);
    printf("%s\n",flag?"Yes":"No");
    for(int i=0;i<n;++i)
        printf("%d%c",in[i],i<n-1?' ':'\n');
    return 0;
}

//如果我的工作能让您得到一些帮助,那就是我最大的荣幸。
//ps:如果您能点一下赞,我就更荣幸了,哈哈O(∩_∩)O


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值