树结构--介绍--二叉树遍历的递归实现

 

目录

树 

树的学术名词

树的种类

 二叉树的遍历

算法实现

遍历命名

二叉树的中序遍历

二叉树的后序遍历

二叉树的后序遍历迭代算法

 二叉树的前序遍历

二叉树的前序遍历迭代算法

 


树封面

树 

是一种非线性的数据结构,它是由n(n≥0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

  • 每个节点有零个或多个子节点;
  • 没有父节点的节点称为根节点;
  • 每一个非根节点有且只有一个父节点;
  • 除了根节点外,每个子节点可以分为多个不相交的子树

image-20220909102214728

树的学术名词

  • 根节点(root): 树的最上层的节点,任何非空的树都有一个节点
  • 路径(path): 从起始节点到终止节点经历过的边
  • 父亲(parent):除了根节点,每个节点的上一层边连接的节点就是它的父亲(节点)
  • 孩子(children): 每个节点由边指向的下一层节点
  • 兄弟(siblings): 同一个父亲并且处在同一层的节点
  • 子树(subtree): 每个节点包含它所有的后代组成的子树
  • 叶子节点(leaf node): 没有孩子的节点成为叶子节点

树的种类

无序树:树中任意节点的子结点之间没有顺序关系,这种树称为无序树,也称为自由树;

有序树:树中任意节点的子结点之间有顺序关系,这种树称为有序树;

二叉树:每个节点最多含有两个子树的树称为二叉树;

满二叉树:所有节点均含有两个子树的树被称为满二叉树;

完全二叉树:除最后一层外,所有层都是满节点,且最后一层缺右边连续节点的二叉树称为完全二叉树;

哈夫曼树(最优二叉树):带权路径最短的二叉树称为哈夫曼树或最优二叉树。

image-20220912170946925

 二叉树的遍历

所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问

访问结点所做的操作依赖于具体的应用问题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础

算法实现

从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:

  • 访问节点的本身(Node)
  • 遍历该节点的左子树(L)
  • 遍历该节点的右子树 (R)

以上三种操作拥有六种执行顺序:

NLR,LNR,LRN,NRL,RNL,RLN。

但是注意前三种次序和后三种次序对称,所以我们只学习前三种次序

image-20220912185718782

遍历命名

根据访问结点操作发生位置命名:

  • NLR:二叉树的前序遍历(Preorder Traversal 亦称(先序遍历))

    访问根结点的操作发生在遍历其左右子树之前

  • LNR:二叉树的中序遍历(Inorder Traversal)

    访问根结点的操作发生在遍历其左右子树之中(间)

  • LRN:二叉树的后序遍历(Postorder Traversal)

    访问根结点的操作发生在遍历其左右子树之后

     

二叉树的中序遍历

若二叉树非空,则依次执行如下操作:

  1. 遍历左子树
  2. 访问根节点
  3. 遍历右子树

image-20220912185750188

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, val=0, left=None, right=None):
#     self.val = val
#     self.left = left
#     self.right = right
class Solution:def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:# 左 根 右def inorder(root : TreeNode):if not root:returninorder(root.left)res.append(root.val)inorder(root.right)res = list()inorder(root)return res

 

二叉树的后序遍历

若二叉树非空,则依次执行如下操作:

  1. 遍历左子树
  2. 遍历右子树
  3. 访问根节点

image-20220912185833626

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, val=0, left=None, right=None):
#     self.val = val
#     self.left = left
#     self.right = right
class Solution:def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:# 后序遍历的顺序:左 右 根def postorder(root : TreeNode):if not root:returnpostorder(root.left)postorder(root.right)res.append(root.val)res = list()postorder(root)return res

二叉树的后序遍历迭代算法

  1. 建立一个栈,用来存储节点。

  2. 根据根右左的顺序将节点依次压入栈中,在压入栈中的同时,按照顺序把节点里的元素依次压入栈中。输出完毕之后按照顺序弹栈。

  3. 将答案数组进行反转,得到左右根顺序的数组

  4. 输出答案

    image-20220913114354933

期望结果:[9,5,7,4,3]

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, val=0, left=None, right=None):
#     self.val = val
#     self.left = left
#     self.right = right
class Solution:def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:res = []stack = []while root or stack:while root:res.append(root.val)stack.append(root)root = root.rightroot = stack.pop().left #根 右 左的顺序res.reverse() return res

 二叉树的前序遍历

若二叉树非空,则依次执行如下操作:

  1. 访问根节点

  2. 遍历左子树

  3. 遍历右子树

    image-20220912185519144

     

    class Solution:def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:# 创建一个集合存储数据res = []def preorder(root:TreeNode):# 判断root是否有值if not root:returnelse:# 获取根节点res.append(root.val)# 获取左节点preorder(root.left)# 获取右节点preorder(root.right)preorder(root)return res
    

    二叉树的前序遍历迭代算法

  4. 建立一个栈,用来存储节点。
  5. 根据左右根的顺序将节点依次压入栈中,在压入栈中的同时,按照顺序把节点里的元素依次压入栈中。输出完毕之后按照顺序弹栈。
  6. 输出答案。
class Solution:def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:# 创建res存储结果res = []stack = [] # 存储分支节点# 只要root有数据 或者stack的数据while root or stack:# 只要root有数据,第一轮循环把左节点搞定while root:res.append(root.val)stack.append(root)# 获取左节点root = root.left# 取出右节点,遍历root = stack.pop().rightreturn res

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/36672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker安装 elasticsearch-head

目录 前言安装elasticsearch-head步骤1:准备1. 安装docker2. 搜索可以使用的镜像。3. 也可从docker hub上搜索镜像。4. 选择合适的redis镜像。 步骤2:拉取elasticsearch-head镜像拉取镜像查看已拉取的镜像 步骤3:创建容器创建容器方式1&#…

项目经理的会议之道:全参与还是精选参与?

引言 在项目管理中,会议是一个常见的工具,用于沟通信息、解决问题、做出决策等。然而,项目经理是否需要参加所有的会议呢?这是一个值得深思的问题。作为项目经理,我们需要权衡会议的重要性和我们的时间管理。我们不能…

【第一阶段】kotlin的函数

函数头 fun main() {getMethod("zhangsan",22) }//kotlin语言默认是public,kotlin更规范,先有输入( getMethod(name:String,age:Int))再有输出(Int[返回值]) private fun getMethod(name:String,age:Int): Int{println("我叫…

Playwright快速上手-1

前言 随着近年来对UI自动化测试的要求越来越高,,功能强大的测试框架也不断的涌现。本系列主讲的Playwright作为一款新兴的端到端测试框架,凭借其独特优势,正在逐渐成为测试工程师的热门选择。 本系列文章将着重通过示例讲解 Playwright python开发环境的搭建 …

Linux Day07

一、僵死进程 1.1僵死进程产生的原因 子进程先于父进程结束, 而父进程没有获取子进程退出码,释放子进程占用的资源,此时子进程将成为一个僵死进程。 在第一个框这里时父进程子进程都没有结束,显示其pid 父进程是2349,子进程是235…

【Nginx】Nginx网站服务

国外主流还是使用apache;国内现在主流是nginx(并发能力强,相对稳定) nginx:高性能、轻量级的web服务软件 特点: 1.稳定性高(没apache稳); 2.系统资源消耗比较低&#xf…

判断链表有环的证明

目录 1.问题 2.证明 3.代码实现 1.问题 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用…

TansUNet代码理解

首先通过论文中所给的图片了解网络的整体架构: vit_seg_modeling部分 模块引入和定义相关量: # codingutf-8 # __future__ 在老版本的Python代码中兼顾新特性的一种方法 from __future__ import absolute_import from __future__ import division fr…

新基建助推数字经济,CosmosAI率先布局AI超算租赁新纪元

伦敦, 8月14日 - 在英国伦敦隆重的Raffles OWO举办的欧盟数字超算新时代战略合作签约仪式,CosmosAI、Infinite Money Fund与Internet Research Lab三方强强联手,达成了历史性的合作协议,共同迈向超算租赁新纪元。 ​ 这次跨界的合作昭示了全球…

VR家装提升用户信任度,线上体验家装空间感

近些年,VR家装逐渐被各大装修公司引入,VR全景装修的盛行,大大增加了客户“所见即所得”的沉浸式体验感,不再是传统二维平面的看房模式,而是让客户通过视觉、听觉、交互等功能更加真实的体验家装后的效果。 对于传统家装…

BUUCTF 还原大师 1

题目描述: 我们得到了一串神秘字符串:TASC?O3RJMV?WDJKX?ZM,问号部分是未知大写字母,为了确定这个神秘字符串,我们通过了其他途径获得了这个字串的32位MD5码。但是我们获得它的32位MD5码也是残缺不全,E903???4D…

【Vue3】自动引入插件-`unplugin-auto-import`

Vue3自动引入插件-unplugin-auto-import,不必再手动 import 。 自动导入 api 按需为 Vite, Webpack, Rspack, Rollup 和 esbuild 。支持TypeScript。由unplugin驱动。 插件安装:unplugin-auto-import 配置vite.config.ts(配置完后需要重启…

迪瑞克斯拉算法 — 优化

在上一篇迪瑞克斯拉算法中将功能实现了出来,完成了图集中从源点出发获取所有可达的点的最短距离的收集。 但在代码中getMinDistanceAndUnSelectNode()方法的实现并不简洁,每次获取minNode时,都需要遍历整个Map,时间复杂度太高。这…

HTML详解连载(5)

HTML详解连载(5) 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽行高:设置多行文本的间距属性名属性值行高的测量方法 行高-垂直居中技巧 字体族属性名属性值示例扩展 font 复合属性使用场景复合属性示例注意 文本缩进属性…

UG NX二次开发(C#)-CAM自定义铣加工的出口环境

文章目录 1、前言2、自定义铣削加工操作3、出错原因4、解决方案4.1 MILL_USER的用户参数4.2 采用自定义铣削的方式生成自定义的dll4.2 配置加工的出口环境4.3 调用dll5、结论1、前言 作为一款大型的CAD/CAM软件, UG NX为我们提供了丰富的加工模板,通过加工模板能直接用于生成…

DTC服务(0x14 0x19 0x85)

DTC相关的服务有ReadDTCInformation (19) service,ControlDTCSetting (85) service和ReadDTCInformation (19) service ReadDTCInformation (19) service 该服务允许客户端从车辆内任意一台服务器或一组服务器中读取驻留在服务器中的诊断故障代码( DTC )信息的状态…

Web菜鸟教程 - Radis实现高性能数据库

Redis是用C语言开发的一个高性能键值对数据库,可用于数据缓存,主要用于处理大量数据的高访问负载。 也就是说,如果你对性能要求不高,不用Radis也是可以的。不过作为最自己写的程序有高要求的程序员,自然是要学一下的&a…

PHP Mysql查询全部全部返回字符串类型

设置pdo属性 $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

08-1_Qt 5.9 C++开发指南_QPainter绘图

文章目录 前言1. QPainter 绘图系统1.1 QPainter 与QPaintDevice1.2 paintEvent事件和绘图区1.3 QPainter 绘图的主要属性 2. QPen的主要功能3. QBrush的主要功能4. 渐变填充5. QPainter 绘制基本图形元件5.1 基本图像元件5.2 QpainterPath的使用 前言 本章所介绍内容基本在《…

chatserver服务器开发笔记

chatserver服务器开发笔记 1 chatserver2 开发环境3 编译 1 chatserver 集群聊天服务器和客户端代码,基于muduo、redis、mysql实现。 学习于https://fixbug.ke.qq.com/ 本人已经挂github:https://github.com/ZixinChen-S/chatserver/tree/main 需要该项…