数据结构——树和二叉树的基本概念

devtools/2024/10/16 2:23:50/

数据结构——树和二叉树的基本概念

  • 什么是树
    • 二叉树的概念
    • 二叉树和树的区别
  • 满二叉树和完全二叉树
    • 满二叉树
    • 完全二叉树
  • 二叉树的性质

我们今天接着来学习树这部分的内容:

什么是树

在计算机科学中,树(Tree)是一种非线性数据结构,它模拟了现实生活中树的分层结构。这种数据结构由若干个节点(Node)以及连接这些节点的边(Edge)组成,用来表示具有层次关系的信息集合。以下是树的基本概念和关键特征:

  1. 节点与边
  • 节点(Node):树中的基本单元,用于存储数据元素。每个节点可能包含一个特定值(如整数、字符串、对象等)、指向其他节点的引用(也称指针)或其他相关信息。
  • 边(Edge):连接节点之间的连线,表示节点间的父子关系。在树的上下文中,边总是从一个节点(父节点)指向另一个节点(子节点),且无方向的循环(即环)。
    在这里插入图片描述
  1. 层级结构与根节点
  • 层级结构:树中的节点按层次排列,形成自上而下的层次关系。节点之间的层次差异决定了它们的相对位置。
  • 根节点(Root Node):树中唯一没有父节点的节点,位于整个树的最顶层。它是树的起点,所有其他节点都直接或间接地与根节点相连。
    在这里插入图片描述
  1. 子节点与父节点
  • 子节点(Child Node):任何一个节点都可以有零个或多个直接连接在其下的节点,这些节点被称为该节点的子节点。
  • 父节点(Parent Node):与子节点相对应,直接连接在某节点之上的节点称为该节点的父节点。
    在这里插入图片描述
  1. 兄弟节点与后代节点
  • 兄弟节点(Sibling Nodes):具有相同父节点的节点互称为兄弟节点。
  • 后代节点(Descendant Nodes):对于任意节点,其子节点、子节点的子节点,以及以此类推直至最底层的所有节点,统称为该节点的后代节点。
    在这里插入图片描述
  1. 叶子节点与内部节点
  • 叶子节点(Leaf Node):没有子节点的节点,通常位于树的最底层。
  • 内部节点(Internal Node):至少有一个子节点的节点,也称为分支节点或非终端节点。
    在这里插入图片描述
  1. 树的性质
  • 无环性:树是一个无环图,即任意两个节点间不存在通过边形成的循环路径。
  • 唯一路径:对于任意两个不同的节点,树中存在一条且仅有一条从一个节点到另一个节点的路径。
  1. 度与深度
  • 度(Degree):一个节点的度是指它拥有子节点的数量。树的度是指所有节点中最大度数。
  • 深度(Depth):从根节点到某个节点的路径上边的数目,称为该节点的深度。根节点的深度定义为0,整棵树的最大深度称为树的深度
    在这里插入图片描述
  1. 子树
  • 子树(Subtree):以某个节点作为根节点,包含该节点及其所有后代节点的树称为该节点的子树。
    在这里插入图片描述

树的这些特性使得它非常适合用来表示具有层级关系的数据,如文件目录结构、组织架构、家族谱系、网页链接结构、表达式解析树、决策过程等。在算法设计中,树结构常用于实现各种查找、排序、遍历、搜索、压缩和编码等操作,相关的数据结构包括二叉树(Binary Tree)、平衡树(Balanced Tree,如AVL树、红黑树)、B树、B+树、堆(Heap)等。每种特定类型的树都有其特定的属性和用途,旨在优化特定操作的效率。

二叉树的概念

二叉树(Binary Tree)是树形数据结构的一个特殊类型,它具有以下显著特点和属性:

  1. 节点与度

    • 节点(Node):每个二叉树节点包含一个数据元素(或值)、一个指向左子节点的引用(通常称为左指针)以及一个指向右子节点的引用(通常称为右指针)。有些实现中,节点也可能包含一个指向父节点的引用。
    • 度(Degree):二叉树节点的最大度数为2,即每个节点最多可以有两个子节点,分别称为左子节点和右子节点。
  2. 子树划分

    • 左子树(Left Subtree):以某个节点的左子节点为根节点的子树称为该节点的左子树。
    • 右子树(Right Subtree):以某个节点的右子节点为根节点的子树称为该节点的右子树。
  3. 递归定义

    • 二叉树可以为空(即没有任何节点,称为空二叉树)。
    • 或者它是一个根节点加上两棵互不相交的二叉树(即左子树和右子树)。这两棵子树同样遵循二叉树的定义。
  4. 有序性

    • 二叉树的子树之间有明确的顺序关系:左子树总是在右子树之前。这意味着即使两个子节点具有相同的值,它们在树中的位置也不能互换,因为这会改变树的结构。
  5. 特殊类型

    • 满二叉树(Full Binary Tree):所有节点都有两个子节点(除了叶子节点外),且所有叶子节点都在同一层。这样的二叉树是最紧凑的,没有空缺的子节点位置。
    • 完全二叉树(Complete Binary Tree):除了最后一层外,每一层都被完全填满,且所有节点都尽可能靠左排列。最后一层的节点可能不满,但必须从左到右依次分布,不允许中间有空位。
  6. 性质

    • 深度:二叉树的深度是从根节点到最远叶子节点的最长路径上的边数。
    • 高度:二叉树的高度是从根节点到最深叶子节点的最长路径上的边数。对于非空二叉树,深度和高度是相等的。
    • 节点数与深度的关系:在满二叉树和完全二叉树中,节点数与深度之间有确定的数学关系,这有助于高效地进行存储和计算。
  7. 应用

    • 二叉树因其结构特性被广泛应用于各种算法和数据结构中,如:
    • 二叉搜索树(Binary Search Tree, BST):每个节点的值大于其左子树中所有节点的值,小于其右子树中所有节点的值,从而支持快速查找、插入和删除操作。
    • 堆(Heap):是一种特殊的完全二叉树,通常用于实现优先队列,保证父节点的关键字值大于(或小于)其子节点的关键字值。
    • 哈夫曼树(Huffman Tree):用于构建最优前缀码进行数据压缩。
    • 二叉判定树(Binary Decision Tree):用于表示逻辑判断过程或分类模型。
    • 表达式树(Expression Tree):用于表示算术或逻辑表达式的结构。

二叉树提供了灵活且高效的结构来组织和操作具有层次关系的数据,特别是当数据间存在某种特定的比较关系时。通过对二叉树进行遍历(如前序遍历、中序遍历、后序遍历和层次遍历),可以方便地访问、查询、更新或打印树中的信息。各种二叉树的变体和算法设计则进一步优化了特定应用场景下的性能。

二叉树和树的区别

二叉树和树的区别主要在顺序:
结构规则:

树的结构相对宽松,节点之间的连接没有严格的顺序规定,只要保持无环即可。不同的子节点可以有不同的子节点数量,树的形状可以非常多样。
二叉树二叉树的结构更为规范和严格,每个节点的子节点分为左、右两个位置,且每个位置最多容纳一个子节点。这种结构带来了明确的左右子树划分和有序性。

子节点顺序:

树的子节点之间没有明确的顺序关系,除非在特定的树类型(如有序树)中有额外的顺序规定
二叉树二叉树的子节点之间有明确的左右顺序,即使子节点具有相同的值,它们在树中的位置也是固定且不能互换的。
在这里插入图片描述

满二叉树和完全二叉树

满二叉树

满二叉树(Full Binary Tree)是一种特殊的二叉树,具有以下特点和性质:
在这里插入图片描述

  1. 定义

    • 满二叉树是一种深度为h(高度为h)的二叉树,其中每个节点都有两个子节点(除非是叶子节点),即每个非叶子节点的度数均为2。
    • 满二叉树中没有空缺的子节点位置,也就是说,除了叶子节点外,每个节点都有两个子节点。
  2. 结构特征

    • 在满二叉树中,最底层(第h层)的节点都是叶子节点,且这些叶子节点均处于最左边的位置,没有空位。
    • 除叶子节点外,每一层的节点数都恰好是下一层节点数的两倍。
  3. 节点数与深度的关系

  • 对于深度为h的满二叉树,其节点总数N可以通过公式计算:
    N = 2^0 + 2^1 + 2^2 + ... + 2^(h-1) = 2^h - 1
  • 反过来,如果已知满二叉树的节点总数N,其深度h可以通过对数运算求得:
  h = log_2(N+1)
  1. 性质
    • 满二叉树是所有二叉树中最紧凑的一种,空间利用率最高。
    • 满二叉树的深度、高度、节点数之间的关系非常明确,便于进行存储和计算。
    • 满二叉树的前序遍历、中序遍历、后序遍历结果具有固定的规律,可以方便地进行编码和解码。

完全二叉树

完全二叉树(Complete Binary Tree)是二叉树的一个重要子类,它具备以下特点和性质:

  1. 定义

    • 完全二叉树是一种深度为h(高度为h)的二叉树,满足以下条件:
    • 除了最后一层外,每一层的节点数都达到最大值,即第i层(从0开始计数)有2^(i)个节点(i=0, 1, …, h-1)。
    • 最后一层的节点都尽可能靠左排列,即从左到右连续填充,没有中间空位。
    • 允许最后一层的节点数少于最大值,但必须从左到右依次分布,不能有中间空位。
  2. 结构特征

    • 完全二叉树的形态接近满二叉树,但允许最后一层的节点数量不足。最后一层的节点可能不满,但必须从左到右依次分布,不允许中间有空位。
    • 除了最后一层外,完全二叉树的任何一层都与满二叉树的对应层完全相同。
  3. 节点数与深度的关系

    • 对于深度为h的完全二叉树,其节点总数N可以通过以下公式计算:
      N = 2^0 + 2^1 + 2^2 + ... + 2^(h-1) + (最后一层节点数)
      
    • 如果已知完全二叉树的节点总数N,其深度h可以通过对数运算近似求得:
      h ≈ log_2(N)
      
  4. 性质

    • 完全二叉树虽然不如满二叉树那么紧凑,但在实际应用中更为常见,因为它对节点的插入和删除操作具有更好的适应性。
    • 完全二叉树可以采用数组(或类似线性结构)进行高效存储,数组下标与节点的层次关系和位置有直接映射关系。例如,对于深度为h的完全二叉树,第i个节点(从1开始计数)的父节点、左子节点、右子节点在数组中的位置分别为 i / 2、2i、2i + 1(向下取整)。
    • 完全二叉树的前序遍历、中序遍历、后序遍历结果虽不如满二叉树那样具有严格的规律,但仍然具有一定的可预测性。

在这里插入图片描述在这里插入图片描述

二叉树的性质

二叉树具有以下性质:

  1. 性质1在二叉树的第i层上至多有2^(i-1)个结点(i≥1)
    在这里插入图片描述

  2. 性质2深度为k的二叉树至多有2^k-1个结点(k≥1)
    在这里插入图片描述

在这里插入图片描述

  1. 性质3对于一棵非空的二叉树,如果叶子结点数为n0,度数为2的结点数为n2,则有n0=n2+1
    在这里插入图片描述

  2. 性质4具有n个结点的完全二叉树的深度为|log(2^n)+1|
    在这里插入图片描述

  3. 性质5:如果对一棵有n个结点的完全二叉树(其深度为|log(2^n)+1|)的结点按层序编号(从第一层到第层,每层从左到右),对任一结点i(1<=i<=n),有:

    • 如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点
    • 如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i
    • 如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1
      在这里插入图片描述

这些性质对于理解和操作二叉树非常重要,它们可以帮助我们更好地组织和遍历二叉树数据结构


http://www.ppmy.cn/devtools/25890.html

相关文章

RabbitMQ是如何保证消息不被重复消费,或者说是如何保证消息消费时的幂等性的

目录 面试官:RabbitMQ是如何保证消息不被重复消费?或者说是如何保证消息消费时的幂等性的1. 使用唯一业务标识2. 使用RabbitMQ的消息去重插件3. 使用业务逻辑实现幂等性4. 使用消息属性和死信队列5. 使用Spring Boot的重试机制该文章专注于面试,面试只要回答关键点即可,不需…

Vue3[黑马笔记]未完待续

优势 组合式API 同功能相关的内容进行集合式管理使用creat-vue 创建项目 执行npm i下载对应的配置文件项目目录 setup 允许直接在script中编写组合式API组合式api setup 执行时机 1.先于beforeCreat函数 2.setup 函数中获取不到this 3.数据与函数需要在setup最后return才能…

【VSCode调试技巧】Pytorch分布式训练调试

最近遇到个头疼的问题&#xff0c;对于单机多卡的训练脚本&#xff0c;不知道如何使用VSCode进行Debug。 解决方案&#xff1a; 1、找到控制分布式训练的启动脚本&#xff0c;在自己的虚拟环境的/lib/python3.9/site-packages/torch/distributed/launch.py中 2、配置launch.…

k8s复制pod里的文件到宿主机

要在Kubernetes中复制Pod里的文件到宿主机&#xff0c;可以使用kubectl cp命令。以下是一个基本的命令格式和示例&#xff1a; 命令格式: kubectl cp <namespace>/<pod-name>:/path/to/file/in/pod /path/to/target/location/on/host -c <container-name> …

k8sCICD

k8s&&CICD 配置文件数据库网络 配置文件 服务的配置文件属于有状态信息&#xff0c;而服务本身属于无状态&#xff0c;因此我决定将服务源码与配置文件分开存放。 jenkins流水线步骤&#xff1a; 开发人员与运维人员配合更新配置文件仓库&#xff08;Dockerfile、yam…

JWT是什么?如何使用?

JWT是什么&#xff1f;如何使用&#xff1f; 前言什么是JWT&#xff1f;概念工作方式JWT的组成HeaderPayloadSignatrue 实战引入依赖自定义注解定义实体类定义一个JWT工具类业务校验并生成token定义拦截器配置拦截器定义接口方法并添加注解开始验证 使用场景注意事项 JWT与传统…

C程序调用C++函数,以及C++调用C函数

C调用C的自定义函数 main.c如下&#xff0c;需要调用名为Utils.cc源文件里的Init()函数 #include "Utils_C_API.h"int main(int argc, char* argv[]) {InitConnector();return 0; }先编译Utils.cc文件 g -fpic -shared Utils.cc -o libUtils.soUtils.cc里的Init()…

富格林:可信方针实现安全盈利

富格林指出&#xff0c;现货黄金一直以来都是投资者们追捧的热门品种之一。其安全性和保值增值的特性吸引着广大投资者。然而&#xff0c;要在现货黄金市场中取得成功并非易事&#xff0c;是需要一定的可信技巧和方针来支撑的。下面富格林将介绍一些关键的可信方针&#xff0c;…