二叉树基础总结

目录

树的定义:

深度和高度:

二叉树

由来

二叉树种类:

满二叉树:

完全二叉树:

严格二叉树(Strict Binary Tree):

平衡二叉树(Balanced Binary Tree):

二叉搜索树(Binary Search Tree):

线段树:

最小生成树:

存储结构(顺序存储和链式存储)

顺序存储

优点:

缺点:

链式存储

链式存储结构的主要特点包括:

二叉树的遍历

前序遍历

代码实现(递归):

中序遍历

代码实现(递归):

后序遍历

代码实现(递归):

层次遍历:

二叉树的遍历题目(持续更新版)


树的定义:

树(层级结构)是一种重要的非线性数据结构(递归的数据结构),它由n(n≥0)个有限节点组成一个具有层次关系的集合。这些节点具有如下特性:(在一个有效的树中,如果有n个节点,就会有n-1条边。)

  1. 每个节点有零个或多个子节点。
  2. 没有父节点的节点称为根节点。根:树的最顶部的节点,唯一没有双亲的节点。
  3. 每一个非根节点有且只有一个父节点。
  4. 除了根节点外,每个子节点可以分为多个不相交的子树。

树的术语包括:

  1. 结点:使用树结构存储的每一个数据元素都被称为“结点”。
  2. 森林:多棵互不相交的树的集合称为森林。
  3. 有序树和无序树:如果树中结点的子树从左到右看有规定的顺序,这棵树称为有序树;反之称为无序树。

树的最常见实现方式:就是动态创建节点,用指针或者引用把他们链接起来。

如下图:

链接是有方向的,它不是双向而是单向的。当我们遍历一棵树的时候,只能从一个方向进行。

深度和高度:

树的深度(Depth):从根节点开始自顶向下逐层累加,直到最远的叶节点。换句话说,最深的叶结点的深度就是树的深度。如果有多个叶节点位于同一最大深度,那么树的深度就是这个最大深度。因此,树的深度等于树中节点的最大层次。同一深度的节点可以被称为同一级的节点。

树的高度(Height):从树的底层叶节点开始自底向上逐层累加,直到根节点。也就是说,树的高度就是从根节点到最远叶节点的最长路径长度。对于任何树,树的高度等于树的最大层数。

值得注意的是,有些教材或资料在定义树的高度时,可能会将其定义为根节点的高度,即从根节点到最远叶节点的最长路径长度减一。这种定义方式在实际应用中也较为常见。

二叉树

由来

树还有不同的类型,例如二叉树。二叉树是树型结构的一个重要类型,它的每个节点的度(即子节点的数量)不大于2。这意味着二叉树的每个节点最多有两个子节点,通常被称为左子节点和右子节点。

二叉树种类:

满二叉树

是一种特殊的二叉树,其特点是除最后一层外,每一层上的所有节点都有两个子节点。也就是说,如果一个二叉树的深度为K,且结点总数是(2^k) -1,则它就是满二叉树。满二叉树的每一层都包含最大数量的节点,因此在给定深度下,满二叉树具有最多的节点。满二叉树是完全二叉树的特例,完全二叉树是指除最后一层外,其他层的节点数达到最大,且最后一层的节点都集中在左边。在满二叉树中,因为每一层都已经满了,所以它也是一棵完全二叉树。

完全二叉树

是由满二叉树而引出的概念。对于深度为k的有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,这棵二叉树被称为完全二叉树。也就是说,如果对树中的结点按从上至下、从左到右的顺序进行编号,编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树就是完全二叉树。

完全二叉树的特点包括:

  1. 叶子结点只能出现在最下层和次下层。
  2. 最下层的叶子结点集中在树的左部。
  3. 倒数第二层若存在叶子结点,一定在右部连续位置。
  4. 如果结点度为1,则该结点只有左孩子,即没有右子树。
  5. 同样结点数目的二叉树,完全二叉树深度最小。

需要注意的是,满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树。另外,完全二叉树第i层至多有2^(i-1)个节点,共i层的完全二叉树最多有2^i - 1个节点。

严格二叉树(Strict Binary Tree):

是二叉树的一种特殊类型,它的特点是每个非终端节点(非叶子节点)都有且仅有两个子节点。也就是说,在严格二叉树中,不存在只有一个子节点或没有子节点的非终端节点。严格二叉树与满二叉树和完全二叉树有所不同。满二叉树要求除最后一层外,每一层上的所有节点都有两个子节点,而严格二叉树则只要求非终端节点有两个子节点,对叶子节点没有要求。完全二叉树则要求除最后一层外,其他层的节点数达到最大,且最后一层的节点都集中在左边,而严格二叉树则没有这个要求。

平衡二叉树(Balanced Binary Tree):

是一种特殊的二叉树,其特点是在进行插入、删除等操作后,依然能保持树的平衡性,即任何节点的两个子树的高度差的绝对值不超过1。平衡二叉树有多种实现方式,如AVL树和红黑树等。平衡二叉树的重要性在于它能够保证在最坏情况下,查找、插入和删除操作的时间复杂度都是O(log n),这对于处理大量数据非常有效。如果没有平衡性,最坏情况下二叉树可能退化为链表,导致时间复杂度变为O(n)。

二叉搜索树(Binary Search Tree):

又称二叉查找树或二叉排序树,是一种经典的数据结构。它具有以下性质:

  1. 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值。
  2. 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值。
  3. 任意节点的左、右子树也分别为二叉搜索树。

二叉搜索树既可以高效地进行插入、查询和删除操作,又具有数组和链表的特点。在二叉搜索树中,查找、插入和删除的时间复杂度都与树的高度成正比,因此在最理想的情况下,这些操作的时间复杂度都是O(logN)。然而,如果二叉搜索树退化为链表,那么这些操作的时间复杂度将变为O(N)。

为了保持二叉搜索树的平衡,避免退化为链表,可以采用平衡二叉搜索树(Balanced Binary Search Tree)的数据结构,如AVL树、红黑树等。这些数据结构通过旋转和重新平衡操作来保持树的平衡,从而确保操作的时间复杂度始终接近O(logN)。

线段树:

线段树是二叉树搜索树的一种。

 线段树总结-CSDN博客

最小生成树:

 最小生成树(Minimum Spanning Tree, MST)是一个在图论中经常出现的问题,它主要在一个连通的加权无向图中找到一棵包含所有顶点的树,同时使得所有边的权值之和最小。这里的“生成树”是指一个连通无向图的所有顶点构成的极小连通子图,它包含原图中的所有顶点,但只有足以构成一棵树的n-1条边。

最小生成树-CSDN博客 

存储结构(顺序存储和链式存储)

顺序存储

二叉树的顺序存储结构通常使用数组来实现。在顺序存储结构中,二叉树中的每个节点按照完全二叉树的顺序存储在一个数组中。完全二叉树的特性使得这种存储方式成为可能,因为在完全二叉树中,除了最后一层之外,其他层的节点数都是满的,并且最后一层的节点都集中在左边。

对于任意一个在数组中的位置为i的节点,其左孩子节点的位置可以通过计算 2i+1 得到,其右孩子节点的位置可以通过计算 2i+2 得到。同样地,对于任意一个位置为j的孩子节点,其父节点的位置可以通过计算 (j-1)/2 得到。

优点:

顺序存储结构的优点是可以快速地访问任意节点,因为每个节点都有一个固定的数组索引。

缺点:

这种存储方式的缺点也很明显,即它可能会浪费存储空间。因为在二叉树中,如果节点数较少,那么数组中的很多位置可能都是空的。此外,对于非完全二叉树,这种存储方式也无法直接表示。

总的来说,顺序存储结构适用于完全二叉树或者节点数较多的二叉树。对于其他类型的二叉树,或者节点数较少的二叉树,链式存储结构可能是一个更好的选择。

链式存储

链式存储结构,又称为链接存储结构,是一种数据的存储方式。

在这种结构中,每个数据元素(通常称为节点)除了包含自身的信息(称为信息域)外,还包含指向其逻辑关系中的下一个节点的指针(称为指针域)。因此,每个节点都通过其指针域与其逻辑关系中的下一个节点相连。这种存储方式不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构所具有的弱点。

链式存储结构的主要特点包括:

  1. 存储密度比顺序存储结构小,因为每个节点都需要额外的存储空间来存储指向下一个节点的指针。
  2. 插入和删除操作灵活,节点可以被插入到链表的任何位置,包括首、中、末,而且不需要移动其他节点中的指针。
  3. 链表的大小可以按需伸缩,是一种动态存储结构,因此在增加或删除元素时性能更高。
  4. 查找节点时的效率相对较低,因为只能从第一个节点开始逐个查找,直到找到所需的节点。

总的来说,链式存储结构是一种非常有用的数据结构,特别适用于需要频繁进行插入和删除操作的情况。然而,由于其查找效率相对较低,因此在需要频繁查找的情况下可能不是最佳选择。

二叉树的遍历

二叉树的每个节点都只会被访问一次。

二叉树有一个前驱和两个后继。

二叉树的遍历顺序有4种,分别是:前序遍历,中序遍历,后序遍历和层序遍历。

前序遍历

先访问根节点,再访问左右子树。

运动轨迹如下:

 

代码实现(递归):
void Tree(Tree* root) {if (root == NULL) {return;}printf("%d", root->data);Tree(root->L_ch);Tree(root->R_ch);
}

中序遍历

先访问左子树,再访根节点,最后访问右子树。

运动轨迹如下:

代码实现(递归):
void Tree(Tree* root) {if (root == NULL) {return;}Tree(root->L_ch);printf("%d", root->data);Tree(root->R_ch);
}

后序遍历

先左子树,再右子树,最后根节点。

运动轨迹如下:

代码实现(递归):
void Tree(Tree* root) {if (root == NULL) {return;}Tree(root->L_ch);Tree(root->R_ch);printf("%d", root->data);
}

层次遍历:

(哈哈,其实不是很复杂,所以我还是先在这篇博客里面补充一下概念吧)

二叉树的层次遍历,也称为广度优先遍历,其顺序是从二叉树的第一层(根节点)开始,从上至下逐层遍历,同一层中则按照从左到右的顺序对节点逐个访问。在进行层次遍历的时候,一般会使用一个队列结构来辅助实现。具体过程如下:

  1. 首先将根节点入队。
  2. 然后开始一个循环,循环条件为队列不为空。在每次循环中,先取出队首元素并访问,然后将其左孩子和右孩子(如果存在)依次入队。
  3. 重复上述步骤,直到队列为空,此时所有节点都已访问完毕,层次遍历结束。

层次遍历的顺序是逐层遍历,同一层中从左到右的顺序。

二叉树的遍历题目(持续更新版)

二叉树的遍历题型-CSDN博客

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

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

相关文章

DoRA(权重分解低秩适应):一种新颖的模型微调方法

来自:小互 DoRA(权重分解低秩适应):一种新颖的模型微调方法 DoRA在LoRA的基础上进一步发展,通过将预训练权重分解为“幅度”和“方向”两个部分进行微调。 这种权重分解方法允许DoRA更精细地控制模型的学习过程&…

如何将shape数据 导入到Postgresql数据库中(单个和批量)

一. 背景 很多时候我们需要将shape数据导入到Postgresql数据库,将数据db化。 本文主要讲解三种方式: 使用QGIS工具导入(单个)、使用postgresql2 命令工具导入(单个)、使用python脚本批量导入shape数据&…

基于函数计算AIGC生成图应用

目录 基于函数计算部署AIGC应用的主要步骤 创建Stable Diffusion模型的应用 访问应用实现文字生图 函数的查看与管理 基于函数计算部署AIGC应用的主要步骤 用函数计算实现AIGC只要简单的三步,分别是创建应用、运行应用及查看管理。 创建Stable Diffusion模型的应…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(3)数据准备和数据预处理

项目开始,首先要进行数据准备和数据预处理。 数据准备的核心是找到这些数据,观察数据的问题。 数据预处理就是去掉脏数据。 缺失值的处理,格式转换等。 延伸学习: 在人工智能(AI)的众多工作流程中&#…

浏览器url地址栏空格变+号

问题描述,后台返回一个参数携带在url上面,发的时候是空格隔开的字符串,但是到了前端放到地址栏打开是一个号。 类似于 // 后台返回的url https://xxx.com?aaa bxxx // 打开浏览器后地址栏显示的 https://xxx.com?aaabxxx问了一下AI说是空…

k8s ipvs 模式下不支持 localhost:<nodeport>方式访问服务

简介 今天去定位一个nodeport的问题,发现curl 127.0.0.1:32000 访问nodeport的时候会规律的hang住,本来以为是后端服务的问题,但是curl管理ip:nodeport 是正常的。这个就奇怪了,深入研究了下发现 ipvs模式下是不支持这样访问的&a…

Python如何实现定时发送qq消息

因为生活中老是忘记各种事情,刚好又在学python,便突发奇想通过python实现提醒任务的功能(尽管TIM有定时功能),也可定时给好友、群、讨论组发送qq消息。其工作流程是:访问数据库提取最近计划——>根据数据…

2024阿里云服务器配置怎么选择?c7、g7和r7?

阿里云服务器配置怎么选择合适?CPU内存、公网带宽和ECS实例规格怎么选择合适?阿里云服务器网aliyunfuwuqi.com建议根据实际使用场景选择,例如企业网站后台、自建数据库、企业OA、ERP等办公系统、线下IDC直接映射、高性能计算和大游戏并发&…

打开ps显示找不到dll怎么办?这四种方法可快速修复

在计算机操作系统中,当执行某程序或运行特定软件时,如果系统提示“ps显示找不到dll文件”,这其实是一个较为常见的问题现象。动态链接库(DLL)文件是Windows操作系统中不可或缺的重要组件,它包含了大量可被多…

IDEA实现序列化时如何自动生成serialVersionUID

实现步骤:1.安装GenerateSerialVersionUID插件 2.点击idea左上角File -> Settings -> Editor -> Inspections -> 搜索 Serialization issues ,找到 Serializable class without ‘serialVersionUID’ ->打上勾,再点击Apply-&…

简单介绍数据结构的基本概念

数据结构的基本概念 常用术语 数据 数据(Data)是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。例如:整数、字符串、图形、图像、声音和动画等 数据元素 数据元素(Data Element&…

【软考】软件过程

目录 一、说明二、能力成熟度模型(CMM)三、能力成熟度模型集成(CMMI)3.1 说明3.2 阶段式模型3.2 连续式模型 一、说明 1.遵循一系列可预测的步骤(路线图),有助于及时交付高质量的产品 2.软件开发中所遵循的路线图称为软…

每日OJ题_算法_递归③力扣206. 反转链表

目录 力扣206. 反转链表 解析代码 力扣206. 反转链表 206. 反转链表 LCR 024. 反转链表 难度 简单 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,…

顺子日期 蓝桥杯

调用API 思路: 设置Calendar的属性,获取Calendar的毫秒数,转换成指定格式的字符串(yyyyMMdd),判断字符串中是否包含符合条件的,若有就1, 迭代: 每次循环给Calendar加上一天即可 import java.text.SimpleDateFormat; im…

Python中的Lambda函数

Python中的Lambda函数 Python中的Lambda函数是一种小型匿名函数,它是通过关键字lambda来定义的。Lambda函数可以接受任意数量的参数,但只能有一个表达式。 Lambda函数的语法 Lambda函数的语法非常简单,基本形式如下: lambda a…

windows_tcp简单代码

文章内容: 一个简单的显示windows平台下ctcp的代码 客户端代码已上传服务器代码未验证方便自己日后使用 客户端: #if _MSC_VER >1600 //VS2010版本号是1600#pragma execution_character_set("utf-8") #endif #include "mynetdump.h&…

【机构内部教程】Jmeter性能测试【一】:性能测试全套教程

性能测试的概念 性能测试是指通过特定方式,对被测系统按照一定策略施加压力,获取系统 响应时间、TPS(Transaction Per Second)、吞吐量、资源利用率等性能指标,以期保证生产系统的性能能够满足用户需求的过程。 性能…

【漏洞复现-通达OA】通达OA getcallist存在前台SQL注入漏洞

一、漏洞简介 通达OA(Office Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化软件,是与中国企业管理实践相结合形成的综合管理办公平台。通达OA为各行业不同规模的众多用户提供信息化管理能力,包括流程审批、行政办公、日常事务、数据统计…

放弃Dubbo,选择最流行的Spring Cloud微服务架构实践与经验总结

Spring For All 社区作者: 纯洁,原文地址 传送门 上次写了一篇文章叫Spring Cloud在国内中小型公司能用起来吗?介绍了Spring Cloud是否能在中小公司使用起来,这篇文章是它的姊妹篇。其实我们在这条路上已经走了一年多,从16年初到…

vue3 之 数据格式化函数

在很多项目中,都会有数据字典表,前端通过请求后端拿到数据字典表里的数据,一般在页面列表上面状态数据都会是返回的数字,前端需要把数字转换成字典表里对应的数据值,下面写了一个前端写死的数据,stateMap里…