当前位置: 首页 > news >正文

算法通关村第六关——如何使用中序和后序来恢复一颗二叉树

1 树的基础知识

1.1 树的定义

树(Tree):表现得是一种层次关系,为 n ( n ≥ 0 ) n(n≥0) nn0个节点构成的有限集合,当n=0时,称为空树,对于任一颗非空树(n>0),它具备以下性质:

  • ​ 树中有一个根(root)节点,用r表示

  • ​ 其余节点可分为m(m>0)互不相交的有限集 T 1 , T 2 , . . . , T m \bold{T_1,T_2, ...,T_m} T1,T2,...,Tm ,其中每个集合本身又是一棵树,称为原来树的子树(Subtree)。子树不相交;除了根结点外,每个结点有且仅有一个父结点;一颗N个结点的树有N-1条边。

树的一些基本术语

  1. 结点的度(Degree):结点的子树个数
  2. 树的度:树的所有结点中最大的度数
  3. 叶结点(Leaf):度为0的结点
  4. 父结点(Parent):有子树的结点是其子树的根节点的父结点
  5. 子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点;子结点也称孩子结点。
  6. 兄弟结点(Sibling):具有同一父结点的各结点是彼此的兄弟结点。
  7. 路径和路径长度:从结点 n 1 n_1 n1 n x n_x nx的路径为一个结点序列 n , n 2 , . . . , n x n,n_2 ,... , n_x n,n2,...,nx , n i n_i ni n i + 1 n_{i+1} ni+1 的父结点。路径所包含边的个数为路径的长度
  8. 祖先结点(Ancestor):沿树根到某一结点路径上的所有结点都是这个结点的祖先结点。
  9. 子孙结点(Descendant):某一结点的子树中的所有结点是这个结点的子孙。
  10. 结点的层次(Level):规定根结点在1层,其它任一结点的层数是其父结点的层数加1。
  11. 树的深度( Depth):树中所有结点中的最大层次是这棵树的深度。
  12. 森林:由m(m > 0)棵互不相交的树的集合称为森林。
  13. 无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树也称为自由树。
  14. 有序树:树中任意节点之间有顺序关系,这种树称为有序树;
  15. 二叉树:每个结点最多含有两个子树的树称为二叉树

1.2 树的性质

  1. 一个二叉树第i层的最大结点数为: 2 i − 1 , i ≥ 1 2^{i-1},i≥1 2i1,i1

  2. 深度为k的二叉树有最大结点总数为: 2 k − 1 , k ≥ 1 2^k-1,k≥1 2k1,k1

  3. 对任何非空二叉树 T T T ,若 n 0 n_0 n0 表示叶结点的个数, n 2 n_2 n2 是度为2的非叶结点个数,那么两者满足关系 n 0 = n 2 + 1 n_0=n_2+1 n0=n2+1

  4. 具有n个结点的完全二叉树的深度必为 l o g 2 ( n + 1 ) log_2(n+1) log2(n+1)

  5. 对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为 i 2 \frac{i}{2} 2ii=1 时为根,除外)

    对二叉树的重要操作:主要是遍历

满二叉树:如果一棵二叉树只有度为0的节点和度为2的节点,并且度为0的节点在同一层上,则这棵二叉树为满二叉树。

在这里插入图片描述

完全二叉树:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大 值,并且最下面一层的节点都集中在该层最左边的若干位置。
在这里插入图片描述

1.3 树的存储方式

  • 顺序存储结构

    • ​ 完全二叉树:按从上至下、从左到右顺序结构

在这里插入图片描述

  • 链表存储

在这里插入图片描述

1.4 树的遍历方式

  • 深度优先遍历:先往深走,遇到叶子节点再往回走。
    • 前序遍历(中左右)
    • 中序遍历(左中右)
    • 后序遍历(左右中)

在这里插入图片描述

  • 广度优先遍历(层次遍历):一层一层的去遍历,一层访问完再访问下一层。

2 通过序列构造二叉树

2.1 根据后中序列复原二叉树

给定三个序列:

(1) 前序:1 2 3 4 5 6 8 7 9 10 11 12 13 15 14

(2) 中序:3 4 8 6 7 5 2 1 10 9 11 15 13 14 12

(3) 后序:8 7 6 5 4 3 2 10 15 14 13 12 11 9 1

分析

根据后序和中序遍历来复原二叉树的思路就是先根据后序遍历确定根节点,然后中序遍历中根节点左边的是左子树,根节点右边的是右子树。根据中序遍历划分好的左右子树,在后序遍历里划分好左右子树。我们知道后序遍历最后遍历中间结点,那么就可以在后序遍历里划分好的左右子树中确定左右子树的根节点,再返回中序遍历划分左右子树。以此类推,直到复原二叉树。

第一轮:
中: 3 4 8 6 7 5 2 | 10 9 11 15 13 14 12后: 8 7 6 5 4 3 2 | 10 15 14 13 12 11 9第二轮:
中: 3 4 8 6 7 5 | null	    10 | 11 15 13 14 12后: 8 7 6 5 4 3 | null		10 | 15 14 13 12 11第三轮:
中:null | 4 8 6 7 5		null | 15 13 14 12后:null | 8 7 6 5 4 	    null | 15 14 13 12第四轮:
中:null | 8 6 7 5        15 13 14 | null后:null | 8 7 6 5		15 14 13 | null第五轮:
中: 8 6 7 | null			15 | 14后: 8 7 6 | null第六轮:
中: 8 | 7		

复原后的二叉树:

在这里插入图片描述

2.2 根据前中序列复原二叉树

分析

根据前序遍历和中序遍历来复原二叉树,与根据后序遍历和中序遍历复原二叉树不同之处在于前序遍历先遍历根结点,再遍历左右结点。先根据前序遍历找到根结点,再在中序遍历中划分左右子树,之后根据中序遍历划分的左右子树来对前序遍历的左右子树进行划分,之后再找左右子树的根结点。以此类推,直到复原。

过程不再赘述,与根据后序遍历和中序遍历复原二叉树大同小异。

http://www.lryc.cn/news/115818.html

相关文章:

  • leetcode算法题--判断是否能拆分数组
  • 基于Flask的模型部署
  • 【资料分享】全志科技T507-H开发板规格书
  • 2023华数杯数学建模C题思路 - 母亲身心健康对婴儿成长的影响
  • 【Kaggle】Identify Contrails to Reduce Global Warming 比赛数据集的可视化(含源代码)
  • Spring(12) BeanFactory 和 ApplicationContext 区别
  • git的日常使用
  • 【Spring Boot】请求参数传json对象,后端采用(pojo)CRUD案例(102)
  • layui之layer弹出层的icon数字及效果展示
  • Python selenium对应的浏览器chromedriver版本不一致
  • Redis的安装方法与基本操作
  • 选读SQL经典实例笔记20_Oracle语法示例
  • JAVA细节/小技巧
  • jmeter如何压测和存储
  • 一个月学通Python(三十三):Python并发编程在爬虫中的应用
  • HCIP——STP
  • 【数据结构】“单链表”的练习题
  • 项目实战 — 消息队列(5){统一硬盘操作}
  • 【2.2】Java微服务:Hystrix的详解与使用
  • 【PYTHON】WebSocket服务端与客户端通信实现
  • Runloop 的五种mode
  • C++头文件使用精要
  • Flink之SideOutput(数据分流)
  • Android Studio新版本logcat过滤说明
  • carsim与matlab仿真
  • rust里如何快速实现一个LRU 本地缓存?
  • MQTT 订阅接收消息 mosquitto 方式
  • 以mod_jk方式整合apache与tomcat(动静分离)
  • springboot动态数据源切换
  • 代码随想录训练营day14