009树的原理应用

树与二叉树核心知识点笔记

一、树的概念和原理

1. 基本定义

树是一种非线性层次结构,用于描述数据元素之间“一对多”的逻辑关系,广泛应用于现实场景(如公司组织架构、家族族谱、院系关系等)。其严格数学定义如下:

  • 树是n个结点的有限集,n=0时称为空树;
  • 非空树有且仅有一个根节点(无直接前驱节点);
  • 除根节点外,其余任意节点有且仅有一个直接前驱,零个或多个直接后继;
  • 当n>1时,其余节点可分为m个(m≥1)互不相交的有限集(T₁、T₂、…、Tₘ),每个集合本身也是一棵树(称为根的子树)。

image-20260109085546605

2. 核心术语

  • 双亲/孩子:若结点有子树,该结点称为子树根的“双亲”,子树根称为该结点的“孩子”;
  • 兄弟:具有相同双亲的结点互称兄弟;
  • 祖先/子孙:从根节点到某结点路径上的所有结点,称为该结点的“祖先”;以某结点为根的子树中所有结点,称为该结点的“子孙”;
  • 结点的度:结点拥有的子树数量;
  • 叶子结点:度为0的结点(无子女,位于树的最底层);
  • 分支结点:度不为0的结点(非叶子结点,包括根节点);
  • 树的深度(高度):树的最大层数(规定根节点为第一层)。
image-20260109090135450

结点A的度是2,结点B的度是1,结点H的度是2,结点C的度是3。结点D、E、F、G、I都是叶子结点,对于A、B、H、C都是分支结点。

对于树A一共有4层,所以树A的深度就是4,对于子树B的深度是3,对于子树H的深度是2

二、二叉树的种类说明

二叉树是特殊的树结构,核心特征为每个结点至多有2棵子树(左子树、右子树),子树有明确次序(左、右不能随意调换),属于有序树。

1. 基本形态

二叉树有5种基本形态:

  • 空树(无任何结点);
  • 仅根节点(无左、右子树);
  • 根节点+左子树(无右子树);
  • 根节点+右子树(无左子树);
  • 根节点+左子树+右子树(完整二叉树结构)。

image-20260109090657524

2. 常见类型

(1)斜树

  • 定义:仅包含左子树的二叉树称为“左斜树”,仅包含右子树的二叉树称为“右斜树”;
  • 特点:退化为线性结构(与链表等价),无法体现二叉树的高效性。

image-20260109090729723

(2)满二叉树

  • 定义:高度为h的二叉树,结点总数为 (2^h - 1);
  • 核心特征:所有结点的度均为2(无单分支结点),叶子结点全部集中在最下层。

image-20260109090750203

(3)完全二叉树

  • 定义:最下面两层的结点度可小于2,结点按“从上到下、从左到右”的顺序连续编号,最下层的叶子结点集中在左侧;
  • 关键关系:满二叉树是特殊的完全二叉树,但完全二叉树不一定是满二叉树。

image-20260109090802421

(4)二叉查找树(BST,Binary Search Tree)

又称二叉搜索树、二叉排序树,结点包含键值(key),满足以下规则:

  1. 左子树中所有结点的键值 < 根结点的键值;
  2. 右子树中所有结点的键值 > 根结点的键值;
  3. 左、右子树也分别是二叉查找树(键值不重复);
  • 核心特性:最小结点在左子树的最末端(持续向左遍历),最大结点在右子树的最末端(持续向右遍历)。

image-20260109090823510

(5)平衡二叉树

  • 定义:树中任一结点的左、右子树深度之差不超过1
  • 核心作用:避免二叉查找树退化为斜树,保证查找、插入、删除操作的时间复杂度稳定在O(log n)。

image-20260109093601630

3. 二叉查找树核心操

(1)插入操作

  • 核心逻辑:从根节点开始,将待插入值与当前结点键值比较;小于当前结点键值则向左子树移动,大于则向右子树移动;找到空位置后,插入新结点作为叶子。
  • 示例:插入数字1到键值为[15,9,23,3,12,17,28,8]的BST中,路径为15→9→3→插入3的左下方。

(2)删除操作

需保持BST的核心规则,分3种情况处理:

  1. 删除叶子结点(度为0):直接删除该结点,无需调整其他结点;
  2. 删除单分支结点(度为1):删除目标结点后,将其子结点替换到目标结点的位置;
  3. 删除双分支结点(度为2):删除目标结点后,用其左子树的最大结点(左子树最右侧结点)或右子树的最小结点(右子树最左侧结点)替换,再递归删除替换结点。

(3)查找操作

  • 核心逻辑:从根节点开始,待查找值小于当前结点键值则向左子树移动,大于则向右子树移动;若键值匹配则找到目标结点,若遍历至空结点则表示不存在该值。

image-20260109094004543

image-20260109094010698

image-20260109094017069

image-20260109094021057

image-20260109094025518

image-20260109094029130

image-20260109094034664

image-20260109094038074

image-20260109094042559

image-20260109094047447

三、二叉树的性质说明

1. 核心性质

性质编号 具体描述 示例验证
性质1 叶子结点数 (n_0 = 双分支结点数n_2 + 1);
总结点数 (n = n_0 + n_1 + n_2)((n_1) 为单分支结点数)
若某二叉树有3个叶子结点((n_0=3))、1个单分支结点((n_1=1))、2个双分支结点((n_2=2)),则总结点数=3+1+2=6
性质2 第i层最多有 (2^{i-1}) 个结点(i≥1) 高度为4的满二叉树,第4层结点数= (2^{4-1}=8)
性质3 高度为h的二叉树最多有 (2^h - 1) 个结点(满二叉树为结点数最多的情况) 高度为4的满二叉树,总结点数= (2^4 - 1=15)

2.笔试题

笔试题:

img

笔试题:

img

笔试题:

img

笔试题:

img

笔试题:

img

四、二叉树的存储结构

1. 顺序结构(数组存储)

  • 存储规则:采用地址连续的内存单元(数组),按“从上到下、从左到右”的顺序存储二叉树结点;编号为i的结点存储在数组下标为i-1的位置(空结点用0表示);

    0表示不存在的空结点。

  • 适用场景:满二叉树、完全二叉树(空间利用率高,可通过数组下标快速计算父子结点关系);

  • 缺点:普通二叉树需用0填充大量空结点,导致空间浪费严重。

image-20260109095805097

2. 链式结构(二叉链表)

  • 结构设计:每个结点包含3个部分——数据域(存储键值)、左子树指针域(指向左孩子结点)、右子树指针域(指向右孩子结点);

    采用双向不循环链表的方案

    链式结构就可以有效的解决数组中存储空结点的问题,链式结构不受内存的限制

  • 优点:无空间浪费,可存储任意形态的二叉树,插入/删除操作灵活;

image-20260109095846580

五、二叉树的遍历说明

image-20260109100517546

image-20260109100524560

image-20260109100533033

1. 核心遍历方式

遍历是从根节点出发,依次访问所有结点(每个结点仅访问一次),是二叉树数据读取的核心方式,常用3种遍历策略。

  • 前序遍历
  • 中序遍历
  • 后序遍历。

前,中,后指的是根结点打印的顺序

(1) 前序遍历(根结点--->左子树--->右子树) A B D G H C E I F

img

(2) 中序遍历(左子树--->根结点--->右子树) G D H B A E I C F

img

(3) 后序遍历(左子树--->右子树--->根结点) G H D B I E F C A

img

2. 遍历应用:还原二叉树

已知两种遍历序列可唯一还原二叉树(前序+中序、后序+中序),步骤如下:

  1. 从前序序列的第一个元素或后序序列的最后一个元素确定根节点;
  2. 在中序序列中找到根节点的位置,分割出左子树和右子树的中序序列;
  3. 根据左、右子树的中序序列长度,分割前序/后序序列,得到左、右子树的前序/后序序列;
  4. 递归执行上述步骤,直至还原整个二叉树。
  • 示例:前序序列ABDEGHCF,中序序列DBGEHACF → 还原后后序序列为DGHEBFCA。

3.笔试题

笔试题:

img

笔试题:

img

笔试题:

img

算法题01:

img

算法题02:

img

算法题03:

img

六、删除二叉查找树中的结点

从二叉查找树删除某个结点比插入结点要麻烦一点,但是删除结点之后也必须遵循“小--中--大”的原则。删除结点的时候就可能会出现以下几种情况:

(1) 要删除的结点的键值比根结点小,则在根结点的左子树进行递归的删除

(2) 要删除的结点的键值比根结点大,则在根结点的右子树进行递归的删除

(3) 如果要删除的结点恰好是根结点,也会遇到以下三种情况:

1. 如果根结点有左子树,需要从左子树中找到键值最大的结点去替换根结点,然后在左子树中把原来的键值最大的结点递归的删掉
2. 如果根结点有右子树,需要从右子树中找到键值最小的结点去替换根结点,然后在右子树中把原来的键值最小的结点递归的删掉
3. 如果根结点没有左子树和右子树,则直接把根结点删掉

img

可以看到,如果要删除的结点是15,该结点有左子树,所以需要从左子树中找到键值最大的结点,也就是13,然后把13替换到15的位置,最后把多余13删掉即可。

img

可以看到,如果要删除的结点是25,该结点有右子树,所以需要从右子树中找到键值最小的结点,也就是26,然后把26替换到25的位置最后把多余26删掉即可。

posted @ 2026-01-09 11:12  郭小胖  阅读(8)  评论(0)    收藏  举报