题意:

给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

思路:

后序遍历序列 = 左子树遍历序列 + 右子树遍历序列 + 根节点。

中序遍历序列 = 左子树遍历序列 + 根节点 + 右子树遍历序列。

找到根节点,再利用根节点计算新的后、中遍历序列端点。

Tips:

注意建树时传根节点的引用。

#include <bits/stdc++.h>
using namespace std; const int M=35;
int n,a[M],b[M];//a数组储存后序遍历,b数组储存中序遍历 map<int,int> posb;//后序遍历中某点在中序遍历中的位置 struct Bt{//二叉树结点
int v;
Bt *l,*r;
}*root; void build_tree(Bt* & rt,int l1,int r1,int l2,int r2){//l1~r1为该树的后序遍历序列区间,l2~r2为中序遍历序列区间。
if(l1>r1||l2>r2){//若不存在有效遍历
rt=nullptr;
return;
}
rt=new(Bt);
rt->v=a[r1];//后序倒数第一个即为该子树的根节点
int mid=posb[a[r1]];//该端点在中序遍历中的位置
int len=mid-l2;//左子树的长度
build_tree(rt->l,l1,l1+len-1,l2,mid-1);//递归建立左子树
build_tree(rt->r,l1+len,r1-1,mid+1,r2);//递归建立右子树
} void Print_level(Bt* t){
queue<Bt*> q;
cout<<(t->v);
if(t->l!=nullptr) q.push(t->l);
if(t->r!=nullptr) q.push(t->r);
while(!q.empty()){
Bt* t=q.front();
q.pop();
if(t!=nullptr){
cout<<' '<<(t->v);
if(t->l!=nullptr) q.push(t->l);
if(t->r!=nullptr) q.push(t->r);
}
}
} int main(){
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++){
cin>>b[i];
posb[b[i]]=i;
}
build_tree(root,0,n-1,0,n-1);
Print_level(root);
return 0;
}

最初的做法:

#include <bits/stdc++.h>
using namespace std; const int M=35; struct Bt{
int v;
Bt *l,*r;
}; int n,a[M],b[M];//a数组储存后序遍历,b数组储存中序遍历
map<int,int> posa,posb;//某值在后序、中序遍历中的位置 Bt *root; void build_node(Bt* & pre,int last,int l,int r){//last为根节点的位置,l~r为中序遍历的左右端点
pre=new(Bt);
pre->v=a[last]; int mid=posb[a[last]];//查找在中序遍历的位置
int last1=-1,last2=-1;
int l1=l,r1=mid-1;//计算根节点两边区间的端点
int l2=mid+1,r2=r; for(int i=l1;i<=r1;i++)//枚举该子树结点在后序遍历中的位置,最大值即为该子树根节点的位置
last1=max(last1,posa[b[i]]);
for(int i=l2;i<=r2;i++)
last2=max(last2,posa[b[i]]); if(l1<=r1)//如果中序遍历区间有效,继续建立子树结点
build_node(pre->l,last1,l1,r1);
else
pre->l=nullptr;
if(l2<=r2)
build_node(pre->r,last2,l2,r2);
else
pre->r=nullptr;
} void Print_level(Bt* t){
queue<Bt*> q; cout<<(t->v);
if(t->l!=nullptr) q.push(t->l);
if(t->r!=nullptr) q.push(t->r); while(!q.empty()){
Bt* t=q.front();
q.pop(); if(t!=nullptr){
cout<<' '<<(t->v);
if(t->l!=nullptr) q.push(t->l);
if(t->r!=nullptr) q.push(t->r);
}
}
} int main()
{
cin>>n; for(int i=0;i<n;i++){
cin>>a[i];
posa[a[i]]=i;
} for(int i=0;i<n;i++){
cin>>b[i];
posb[b[i]]=i;
} build_node(root,n-1,0,n-1); Print_level(root); return 0;
}

GPLT L2-006 树的遍历(二叉树)的更多相关文章

  1. PTA L2-006 树的遍历-二叉树的后序遍历+中序遍历,输出层序遍历 团体程序设计天梯赛-练习集

    L2-006 树的遍历(25 分)   给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(≤),是二叉树中结点的 ...

  2. GPTL—练习集—006树的遍历

    #include<bits/stdc++.h> using namespace std; typedef int daTp;//datatype typedef struct BTNode ...

  3. L2-006 树的遍历 (25 分) (根据后序遍历与中序遍历建二叉树)

    题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805069361299456 L2-006 树的遍历 (25 分 ...

  4. javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题

    赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...

  5. PTA 7-10 树的遍历(二叉树基础、层序遍历、STL初体验之queue)

    7-10 树的遍历(25 分) 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(≤30),是二叉树中结点的个数 ...

  6. 团体程序设计天梯赛 L2-006. 树的遍历 L2-011. 玩转二叉树

    L2-006. 树的遍历 #include <stdio.h> #include <stdlib.h> #include <string.h> #include & ...

  7. 天梯 L2 树的遍历(已知后序中序求层序)

    树的遍历 (25 分) 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(≤30),是二叉树中结点的个数.第二行 ...

  8. C++树——遍历二叉树

    在讲遍历之前,我们要先创建一个树: #include <iostream> using namespace std; typedef struct node; typedef node * ...

  9. 数据结构算法C语言实现(二十)--- 6.3.1遍历二叉树

    一.简述 二叉树的遍历主要是先序.中序.后序及对应的递归和非递归算法,共3x2=6种,其中后序非递归在实现上稍复杂一些.二叉树的遍历是理解和学习递归及体会栈的工作原理的绝佳工具! 此外,非递归所用的栈 ...

  10. 【面经】用递归方法对二叉树进行层次遍历 && 二叉树深度

    void PrintNodeAtLevel(BiTree T,int level) { // 空树或层级不合理 ) return; == level) { cout << T->da ...

随机推荐

  1. Java NIO 缓冲区 Buffer

    缓冲区 Buffer 是 Java NIO 中一个核心概念,它是一个线性结构,容量有限,存放原始类型数据(boolean 除外)的容器. 1. Buffer 中可以存放的数据类型 java.nio.B ...

  2. 【Dart】语言概述

    // 导入(import) // 导入核心库 //导入外部库 import 'package:test_api/test_api.dart'; // 导入文件 //import 'path/test. ...

  3. CopyOnWriteArrayList设计思路与源码分析

    CopyOnWriteArrayList实现了List接口,RandomAccess,Cloneable,Serializable接口. CopyOnWriteArrayList特性 1.线程安全,在 ...

  4. Centos 6 下安装 OSSEC-2.8.1 邮件告警 (二)

    Ossec 配置邮件通知 ## 1 安装软件包: yum install -y sendmail mailx cyrus-sasl cyrus-sasl-plain #安装postfix邮件相关的软件 ...

  5. 【分布式锁的演化】终章!手撸ZK分布式锁!

    前言 这应该是分布式锁演化的最后一个章节了,相信很多小伙伴们看完这个章节之后在应对高并发的情况下,如何保证线程安全心里肯定也会有谱了.在实际的项目中也可以参考一下老猫的github上的例子,当然代码没 ...

  6. QLibrary 加载动态库

    阅读本文大概需要 6.6分钟 一般情况下在没有头文件支持情况下,想要引入某个动态库,最好的办法就是使用「动态加载」的方法,在Qt中一般使用QLibyary来操作 常用 api QLibrary(con ...

  7. 【Linux】dlopen failed: /lib/lsiRAID.so: cannot open shared object file: No such file or directory

    遇到这个问题,首先第一反应,是看其他的服务器中是否有这个库文件,如果有的话直接cp过来一份就行 但是检查发现,其他的系统中也不存在lsiRAID.so这个库文件,很神奇.. 但是看日志持续报错,查看s ...

  8. 【Oracle】归档日志的删除操作

    [root@sha3 oracle]# rman target / Recovery Manager: Release 10.2.0.4.0 - Production on Tue Jan 20 01 ...

  9. 【ORA】ORA-01756: quoted string not properly terminated

    出现ORA-01756: quoted string not properly terminated 后,查看SQL是否有中文符号 修改为英文的符号,运行正常

  10. Array.of使用实例

    Array.of是es6新增的API,其实粗暴点理解,光看of,就可以猜到它是数组的意思,所以猜测可以用来把字符串转换成数组. 像这样的table,有批量删除和单个删除的功能,,但是又不想写两个方法, ...