PATA 1020 Tree Traversals

在这里插入图片描述
题记
思路
1.创建结点的结构体
2.根据中序遍历和后序遍历递归地创建二叉树。假设中序遍历当前的树下标为inL,inR,后序遍历当前的树下标是poL,poR。后序遍历最后一个就是根结点,循环中序遍历找到根结点,记录下标为k,中序遍历左边的是左子树,右边的是右子树,得到左子树结点个数为numLeft=k-inL,于是得到当前的树的左子树中序遍历下标范围为[intL,K-1],后序遍历为[poL,poL+numLeft-1],右子树中序遍历下标范围为[k+1,inR],后序遍历下标范围为[poL+numLeft,poR].
3.利用队列层次遍历得到的树
总结:
1.中序序列可以与先序序列,后序序列和层次序列中的任意一个来构建唯一的二叉树,而后三者两两搭配或是三个一起都无法构建唯一的二叉树。原因是后三者均是提供根节点,作用是相同的,都无法区分出左右子树。
2.BFS用的队列的元素是结点指针类型,这道题其实可以只用普通的节点类型就可以。为什么要用指针呢?因为有些题目需要修改结点的某些值,队列里压进去的只是原来的结点的副本,修改队列中的元素不改变原结点,这点需要注意,最好养成习惯用指针。

代码如下

#include <iostream>
#include <queue>
using namespace std;

const int Maxn=30+5;

struct node{
    int data;
    node* lchild;
    node* rchild;
};

//输入
int n;
int inorder[Maxn],postorder[Maxn];

node* create(int inL,int inR,int poL,int poR){
    //当inL==inR时是一个叶子结点还可以继续
    if(inL>inR)
        return NULL;
    node* root=new node;
    root->data=postorder[poR];
    int k;
    //找到中序遍历中的根节点,k保存中序遍历到根的下标
    for(k=inL;k<=inR;k++){
        if(inorder[k]==root->data)
            break;
    }
    //左子树的节点数
    int numLeft=k-inL;
    root->lchild=create(inL,k-1,poL,poL+numLeft-1);
    root->rchild=create(k+1,inR,poL+numLeft,poR-1);
    return root;
}

int num=0;//已经输出的结点数,为了避免最后多一个空格
void BFS(node* root){
    //注意元素类型是结点指针
    queue<node*> q;
    q.push(root);
    while(!q.empty()){
        node* now=q.front();
        q.pop();
        num++;
        if(num<n)
            printf("%d ",now->data);
        else
            printf("%d",now->data);
        if(now->lchild!=NULL)
            q.push(now->lchild);
        if(now->rchild!=NULL)
            q.push(now->rchild);
    }
}


int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&postorder[i]);
    for(int i=0;i<n;i++)
        scanf("%d",&inorder[i]);
    node* root=create(0,n-1,0,n-1);
    BFS(root);//层序遍历
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值