二叉树(详解)

在了解二叉树之前呢我们先来了解一下树形结构,因为二叉树就是树形结构的一种特殊情况,它有这非常好的性质,是很常用的一种结构。

目录

一.什么是树形结构?

二.树形结构常见的名词

三.树的存储

四.二叉树

1.二叉树的概念

2.现实中的二叉树

3.特殊二叉树

3.1.完全二叉树

3.2.满二叉树

4.二叉树的存储结构


一.什么是树形结构?

树形结构指的是在**++逻辑结构++** 上是呈现树状的,类似倒立的树,所以称为树形结构,是非线性的。如下:

除根结点外,其余结点被分成M(M>0)个++互不相交++ 的集合T1、T2、......、Tm,其中每一个集合Ti(1<= i<= m)又是一棵结构与树类似的子树。++每棵子树的根结点有且只有一个前驱,可以有0个或多个后驱++

二.树形结构常见的名词

  • 结点的度:一个结点含有的子树的个数称为该结点的度; 如上图:F的为3
  • 树的度:一棵树中,最大的结点的度称为树的度; 如上图:树的度为6
  • 叶结点(终端结点):度为0的结点称为叶结点; 如上图:B、C、H、I...等结点为叶结点
  • 分支结点:度不为0的结点; 如上图:D、E、F、G...等结点为分支结点
  • 父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点; 如上图:A是B的父结点
  • 子结点:一个结点含有的子树的根结点称为该结点的子结点; 如上图:B是A的孩子结点
  • 兄弟结点:具有相同父结点的结点互称为兄弟结点; 如上图:B、C是兄弟结点
  • 结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推;
  • 树的高度(深度):树中结点的最大层次; 如上图:树的高度为4
  • 结点的祖先:从根到该结点所经分支上的所有结点;如上图:A是所有结点的祖先
  • 子孙:以某结点为根的子树中任一结点都称为该结点的子孙。如上图:所有结点都是A的子孙
  • 森林:由m(m>0)棵互不相交的树的集合称为森林

三.树的存储

一颗树是怎么储存是一个值得思考的问题,不仅仅是储存数据,而且要使得数据之间的关系(比如父子关系)清晰明了,我们一般从顺序表和链表两个方面来开始考虑,不过这里很显然的是顺序表是行不通的,而这里需要用的也不是真正的链表因为它需要有多个后驱指针,我们并不能确定一个结点的子结点的个数,所以不能给确切后驱指针个数,可以考虑使用一个结构体指针数组来储存,不过这样就太麻烦了而且效率低,可能造成空间浪费。这里有一个非常妙的方法,就是把一个结点的所有兄弟结点用一个链表来储存,所以在设计结构体的时候就只需要创建三个成员,一个用来储存数据,一个用来储存它的子结点,另一个用来储存它的兄弟结点。如下:

cpp 复制代码
typedef int DataType;
struct Node
{
    struct Node* firstChild1; // 第一个孩子结点
    struct Node* pNextBrother; // 指向其下一个兄弟结点
    DataType data; // 结点中的数据域
};

四.二叉树

1.二叉树的概念

二叉树指的是度不超过2的树形结构,也就是说一个节点的子节点最多只能有2个。

它是由根结点和一个左子树和右子树组成

所有的二叉树都是由以下这些情况复合而成:

2.现实中的二叉树

3.特殊二叉树

3.1.完全二叉树

完全二叉树:比如一个深度为h的二叉树,那么第h-1层是满的,并且第h层从左到右叶子结点依次存在。

3.2.满二叉树

满二叉树是一种特殊的完全二叉树它指的是最后一层叶子结点是满的一个深度为h的满二叉树结点个数为2^h-1

3.3.堆

堆就是完全二叉树,而且是一种特殊的完全二叉树,它需要满足每一个父节点都大于子节点,称为大堆,或每一个父节点都小于子节点,称为小堆。而对兄弟节点之间的大小关系并没有要求(为此它并不是有序的)。如下:

4.二叉树的存储结构

二叉树的储存一般是用类似链表来储存的,因为能确定一个结点的度是小于等于2的,所以在设计结构体的时候我们用两个后驱指针成员一个指向左孩子,另一个指向右孩子,如下:

cpp 复制代码
typedef int DataType;
struct Node
{
    struct Node* LeftChild; // 左孩子的节点
    struct Node* RightChild; // 右孩子的节点
    DataType data; // 结点中的数据域
};

对于特殊的二叉树完全二叉树有一个更好的储存方法,就是用顺序表来储存,它的一个很大的好处在于知道一个结点可以很容易的算出它父结点和子结点的下标,还有可以随机访问。

父子结点下标计算公式 :

左子结点下标 = 父结点下标*2+1

右子结点下标 = 父结点下标*2+2

父结点下标 = (子结点下标-1) / 2

这些公式对堆的学习非常重要,下一章我们开始堆的学习。

相关推荐
许愿与你永世安宁27 分钟前
力扣343 整数拆分
数据结构·算法·leetcode
爱coding的橙子30 分钟前
每日算法刷题Day42 7.5:leetcode前缀和3道题,用时2h
算法·leetcode·职场和发展
周树皮不皮31 分钟前
20250704【翻转&二叉树】|Leetcodehot100之226【pass】&今天计划
python
魔芋红茶32 分钟前
spring-initializer
python·学习·spring
ruanjiananquan9932 分钟前
c,c++语言的栈内存、堆内存及任意读写内存
java·c语言·c++
喜欢吃豆36 分钟前
快速手搓一个MCP服务指南(九): FastMCP 服务器组合技术:构建模块化AI应用的终极方案
服务器·人工智能·python·深度学习·大模型·github·fastmcp
一个天蝎座 白勺 程序猿43 分钟前
Python(28)Python循环语句指南:从语法糖到CPython字节码的底层探秘
开发语言·python
满分观察网友z1 小时前
从一次手滑,我洞悉了用户输入的所有可能性(3330. 找到初始输入字符串 I)
算法
持梦远方1 小时前
C 语言基础入门:基本数据类型与运算符详解
c语言·开发语言·c++
abigale031 小时前
webpack+vite前端构建工具 -11实战中的配置技巧
前端·webpack·node.js