• 重建二叉树


    二叉树的遍历方式有4种:先序遍历,中序遍历,后序遍历以及层次遍历

    根据中序遍历和另外任意一种遍历方式都可以唯一的重建二叉树!

    如果没有中序遍历,其余任意两种组合均无法实现二叉树的重建,为什么?

    其实原因很简单,先中后说的均为根结点的顺序,那么左子树一定先于右子树遍历到,中序遍历可以根据根结点,将左右子树分开!

    那么如何根据中序遍历和后序遍历,重建出二叉树?

    思路:假设递归过程中,某一步的后序序列区间为[postL,postR],中序序列区间为[inL,inR];

        1. 根据后序遍历的特点可知,postR位置为根结点;

        2. 从中序序列中,寻找出root的位置k,k左边的均为左子树,右边的均为右子树;

        3. 将左子树区间[postL,k-1]作为新的后序和中序序列,进行递归。

    代码如下:

    /*
     * 给定一个二叉树的后序遍历和中序遍历,重建这个二叉树
     */
    /*
     * 思路:根据后序遍历找到根结点,根据中序遍历,根结点左边为左子树,根结点右边为右子树
     * 边界条件:后序区间为空
     */
    
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    const int maxn=50;
    struct node{
        int data;
        node* lchild;
        node* rchild;
    };
    
    int pre[maxn],in[maxn],post[maxn];
    int n;
    
    node* create(int postL,int postR,int inL,int inR) //后序和中序的区间
    {
        if(postL>postR)
            return NULL; 
        node* root=new node;
        root->data=post[postR];  //后序序列中,最后一个节点为根节点
        int k;
        for(k=inL;k<=inR;k++)
        {
            if(in[k]==root->data)
                break;
        }
        int numLeft=k-inL;  //左子区间为左子树0
        root->lchild=create(postL,postL+numLeft-1,inL,k-1);
        root->rchild=create(postL+numLeft,postR-1,k+1,inR);
        return root;
    }
    
    int num=0;
    
    void BFS(node *root){
        //层次遍历
        queue<node*> q;
        q.push(root);
        while(!q.empty()){
            node* now=q.front();
            q.pop();
            printf("%d",now->data);
            num++;
            if(num<n)
                printf(" ");
            if(now->lchild!=NULL)
                q.push(now->lchild);
            if(now->rchild!=NULL)
                q.push(now->rchild);
        }
    }
    int main()
    {
        scanf("%d",&n);
        int i;
        for(i=0;i<n;i++){
            scanf("%d",&post[i]);
        }
    
        for(i=0;i<n;i++){
            scanf("%d",&in[i]);
        }
    
        node* root=create(0,n-1,0,n-1);
        BFS(root);
    prinf(" ");
    return 0; }

    仅供学习参考!

    测试用例:【PAT A1020】

  • 相关阅读:
    有关 Windows 安全的一些记录
    常用的 PowerShell 脚本命令记录
    FireDAC 数据库开发笔记(2. 快储机制)
    FireDAC 数据库开发笔记(3. 使用内存数据 FDMemTable)
    FireDAC 数据库开发笔记(4. FireDAC 进阶)
    FireDAC 数据库开发笔记( 目录)
    FireDAC 数据库开发笔记(1. 处理数据)
    navicat连接sqlserver报错:[navicat premium] [IM002] [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序
    利用分层机制优化 Docker Image
    重要参考步骤ProxySQL Cluster 集群搭建步骤
  • 原文地址:https://www.cnblogs.com/cnyulei/p/10921567.html
Copyright © 2020-2023  润新知