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

数据结构 -- 树

一、树的基本概念

(一)定义

树是由 n(n ≥ 0) 个结点组成的有限集合,是一种非线性层次结构:

  • 当 n = 0 时,称为空树
  • 当 n > 0 时,存在唯一的根结点(无前驱结点),其余结点可划分为 m(m ≥ 0) 个互不相交的有限子集,每个子集都是一棵独立的子树

(二)结点与树的核心属性

概念定义
结点的度结点拥有的子树个数
叶结点(终端结点)度为 0 的结点(无子树,位于树的最底层)
分支结点(非终端结点)度不为 0 的结点(至少拥有一棵子树)
树的度树中所有结点的最大度数
深度 / 高度从根结点开始计数,根为第 1 层,子结点依次递增,树的最大层数即为深度 / 高度

(三)存储结构

  • 顺序存储:通过数组存储结点,需结合结点间的层次关系(如双亲下标)关联数据,适用于结构规则的树(如完全二叉树)。
  • 链式存储:通过指针记录结点的子树地址(如孩子指针、兄弟指针),灵活性高,适用于各类形态的树。

二、二叉树的基本概念

(一)定义

二叉树是 n(n ≥ 0) 个结点的有限集合,满足:

  • 当 n = 0 时,为空二叉树;
  • 当 n > 0 时,由根结点左子树右子树组成,且左、右子树互不相交,均为二叉树。

(二)核心特点

  1. 每个结点最多有 2 棵子树(左子树和右子树),即二叉树的度最大为 2;
  2. 左、右子树具有有序性,不可随意颠倒(如 “仅有左子树” 与 “仅有右子树” 是两种不同结构);
  3. 若结点仅有一棵子树,必须明确标注是左子树还是右子树。

三、特殊二叉树

类型定义
斜树所有结点仅含一棵子树,分为左斜树(仅左子树)和右斜树(仅右子树)
满二叉树深度为 k(k ≥ 1),所有分支结点均有左、右子树,且所有叶子结点在同一层
完全二叉树深度为 k(k ≥ 1),按层序编号后,与同深度满二叉树的结点编号完全一致

四、二叉树重要性质

  1. 第 i 层结点数上限:第 i(i ≥ 1) 层最多有 2^{i-1} 个结点(如第 3 层最多 4 个结点);
  2. 深度为 k 的结点总数上限:深度为 k(k ≥ 1) 的二叉树,最多有 2^k - 1 个结点(此时为满二叉树);
  3. 叶子结点与度为 2 的结点关系:任意非空二叉树中,叶子结点数 n₀ = 度为 2 的结点数 n₂ + 1(即 n₀ = n₂ + 1);
  4. 完全二叉树深度计算:含 n 个结点的完全二叉树,深度为 ⌊log₂n⌋ + 1⌊x⌋ 表示向下取整)。

五、二叉树遍历方式

二叉树遍历是按规则访问所有结点(每个结点仅访问一次),核心分为深度优先遍历(DFS)和广度优先遍历(BFS):

遍历类型具体方式遍历顺序
深度优先遍历前序遍历根结点 → 左子树 → 右子树
中序遍历左子树 → 根结点 → 右子树
后序遍历左子树 → 右子树 → 根结点
广度优先遍历层序遍历按层次从上到下、同层从左到右

前序遍历
规则是若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子
树,再前序遍历右子树。如图,遍历的顺序为:ABDGHCEIF。

void PreOrder(TreeNode* root) {if (root == NULL) return;  // 空树,递归终止printf("%d ", root->data); // 访问根结点PreOrder(root->left);      // 递归遍历左子树PreOrder(root->right);     // 递归遍历右子树
}

中序遍历
规则是若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结
点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。如图,遍历的顺序为:GDHBAEICF。

void InOrder(TreeNode* root) {if (root == NULL) return;  // 空树,递归终止InOrder(root->left);       // 递归遍历左子树printf("%d ", root->data); // 访问根结点InOrder(root->right);      // 递归遍历右子树
}

3.后序遍历
规则是若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左
右子树,最后是访问根结点。如图,遍历的顺序为:GHDBIEFCA。

void PostOrder(TreeNode* root) {if (root == NULL) return;  // 空树,递归终止PostOrder(root->left);     // 递归遍历左子树PostOrder(root->right);    // 递归遍历右子树printf("%d ", root->data); // 访问根结点
}

遍历顺序:按树的层次从上到下、同一层从左到右依次访问所有结点,本质是 “按层访问”。​实现依赖:需借助队列(先进先出,FIFO),通过 “根结点入队 → 队头出队访问 → 左右子结点入队 → 循环至队空” 的逻辑实现。

void LevelOrder(TreeNode* root) {if (root == NULL) return;          // 空树,直接返回SeqQue* queue = CreateSeqQue(100); // 创建容量为 100 的队列EnterSeqQue(queue, root);          // 根结点入队while (!IsEmptySeqQue(queue)) {    // 队列非空,循环处理TreeNode* curr = GetHeadSeqQue(queue); // 取队头结点printf("%d ", curr->data);     // 访问当前结点QuitSeqQue(queue);             // 队头结点出队if (curr->left != NULL)        // 左子结点非空,入队EnterSeqQue(queue, curr->left);if (curr->right != NULL)       // 右子结点非空,入队EnterSeqQue(queue, curr->right);}DestroySeqQue(queue);              // 销毁队列,释放内存
}

http://www.xdnf.cn/news/1345627.html

相关文章:

  • STM32G4-比较器
  • 亚马逊老品怎么再次爆发流量?
  • 计算机内存中的整型存储奥秘、大小端字节序及其判断方法
  • 量子计算基础
  • 豆包AI PPT与秒出PPT对比评测:谁更适合你?
  • 树莓派安装pyqt5 opencv等库一些问题
  • 使用 YAML 文件,如何优雅地删除 k8s 资源?
  • 高并发用户数峰值对系统架构设计有哪些影响?
  • .java->.class->java 虚拟机中运行
  • 设计模式:抽象工厂模式
  • 实验二 Cisco IOS Site-to-Site Pre-share Key
  • 异质结3.0时代的降本提效革命:捷造科技设备技术创新与产业拐点分析
  • 高级SQL优化 | 告别 Hive 中 GROUP BY 的大 KEY 数据倾斜!PawSQL 自适应优化算法详解
  • Logstash——输出(Output)
  • 大视协作码垛机:颠覆传统制造,开启智能工厂新纪元
  • 【CV】OpenCV①——图形处理简介
  • 2025年视频大模型汇总、各自优势及视频大模型竞争焦点
  • 掌握设计模式--命令模式
  • WebRTC 结合云手机:释放实时通信与虚拟手机的强大协同效能
  • elasticsearch的使用
  • C#_高性能内存处理:Span<T>, Memory<T>, ArrayPool
  • vue vxe-gantt 甘特图自定义任务条样式模板 table 自定义插槽模板
  • Vue2 响应式系统设计原理与实现
  • 【Java并发编程】Java多线程深度解析:状态、通信与停止线程的全面指南
  • 多态(polymorphism)
  • celery
  • 学习python第12天
  • 基于Python的伊人酒店管理系统 Python+Django+Vue.js
  • 探索Thompson Shell:Unix初代Shell的智慧
  • Linux之Ubuntu入门:Vmware中虚拟机中的Ubuntu中的shell命令-常用命令