从链表到二叉树:树形结构的入门与核心性质解析
- [Bilibili 同步视频](#Bilibili 同步视频)
- [一、现实树 vs 计算机树:反向生长的"倒栽葱"](#一、现实树 vs 计算机树:反向生长的“倒栽葱”)
- 二、链表与树的关联:链表是特殊的树形结构
- 三、二叉树:树形结构的核心(重点)
-
- [1. 二叉树节点定义(C++标准版)](#1. 二叉树节点定义(C++标准版))
- [2. 二叉树结构示例](#2. 二叉树结构示例)
- [3. 示例二叉树初始化(C++)](#3. 示例二叉树初始化(C++))
- 四、节点的"度":衡量分叉能力的关键
- 五、二叉树经典性质(必记)
- 六、写在最后
Bilibili 同步视频
🌳 数据结构是程序设计的基石,树形结构更是贯穿各类技术场景(数据库索引、文件系统等)的核心。二叉树作为树形结构的经典代表,是每个程序员的必备知识点。本文从现实场景出发,简化拆解从链表到二叉树的演变、核心定义及经典性质,帮你快速吃透底层逻辑!
一、现实树 vs 计算机树:反向生长的"倒栽葱"
现实中的树:根在地下,向上分叉、枝繁叶茂,遵循"根→树干→枝叶"的生长逻辑。
计算机中的树:恰好相反,是"倒栽葱"结构------根节点在最上方,叶子节点在最下方,通过节点与有向边的指向关系,实现层级关联。
【文本绘制:结构对比】
现实树: 枝叶 → 树干 → 树根(地下)
计算机树:根节点(1)→ 子节点(2、3、4)→ 叶子节点(5、6)
核心本质:计算机树 = 节点(存储数据) + 有向边(表示层级关系)。
二、链表与树的关联:链表是特殊的树形结构
💡 核心结论:链表是一种特殊的树形结构,二者的核心区别的在于指针域的指向能力。
-
链表:每个节点只有1个指针域,仅能唯一指向一个后继节点,呈线性结构(一对一关联);
-
树形结构:将单一指针域改为数组指针域,可指向多个子节点,实现"分叉"(一对多关联)。
【文本绘制:树转链表示意】
原始树:根(1)→ [2、3、4] → 2→5,4→[5、6] → 砍去多余分支 → 链表:1→2→5
C++代码对比(核心差异)
cpp
// 1. 链表节点(单一指针域)
struct ListNode {
int val;
ListNode* next; // 仅指向1个后继节点
ListNode(int x) : val(x), next(nullptr) {}
};
// 2. 树形节点(数组指针域,以三叉树为例)
#include <vector>
using namespace std;
struct TreeNode {
int val;
vector<TreeNode*> children; // 可指向多个子节点
TreeNode(int x) : val(x) {}
};
注:每个节点最多有3个指针域的树,称为三叉树;多余指针域指向nullptr(空节点)。
三、二叉树:树形结构的核心(重点)
📌 定义:每个节点最多有2个指针域,分别称为左孩子(left)和右孩子(right),分叉方向严格限定为左右,是应用最广泛的树形结构。
1. 二叉树节点定义(C++标准版)
cpp
struct BinaryTreeNode {
int val; // 数据域
BinaryTreeNode* left; // 左孩子指针
BinaryTreeNode* right; // 右孩子指针
// 构造函数(默认左右孩子为空)
BinaryTreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
2. 二叉树结构示例
【文本绘制:经典二叉树】
根(1)
/
2 3
/ \
4 5 6
结构说明:根节点1的左孩子为2、右孩子为3;节点2有左右孩子4、5;节点3只有右孩子6;4、5、6为叶子节点(无孩子)。
3. 示例二叉树初始化(C++)
cpp
int main() {
// 创建所有节点
BinaryTreeNode* root = new BinaryTreeNode(1);
BinaryTreeNode* node2 = new BinaryTreeNode(2);
BinaryTreeNode* node3 = new BinaryTreeNode(3);
BinaryTreeNode* node4 = new BinaryTreeNode(4);
BinaryTreeNode* node5 = new BinaryTreeNode(5);
BinaryTreeNode* node6 = new BinaryTreeNode(6);
// 建立左右孩子关联
root->left = node2; root->right = node3;
node2->left = node4; node2->right = node5;
node3->right = node6;
return 0;
}
四、节点的"度":衡量分叉能力的关键
📌 定义:节点的度 = 该节点拥有的孩子节点数量(不包含空指针),分为3类:
-
度为0:无孩子(叶子节点,如4、5、6);
-
度为1:仅有1个孩子(如节点3,只有右孩子6);
-
度为2:有2个孩子(如节点1、2)。
小科普:"度"源自图论,树形结构中的"度"本质是图论中的"出度"(节点指向其他节点的边数),无需复杂记忆,记住"度=孩子数"即可。
五、二叉树经典性质(必记)
✅ 核心性质:任意二叉树中,度为0的叶子节点数(n0)= 度为2的节点数(n2)+ 1,无例外!
简化推导(初中数学可懂)
-
前提1:总节点数N = 度为0节点数(n0)+ 度为1节点数(n1)+ 度为2节点数(n2);
-
前提2:N个节点的树,必有N-1条边(树的基本特征);
-
推导:边数 = 所有节点度之和(度为0贡献0条,度1贡献1条,度2贡献2条),即边数 = n1 + 2n2;
-
联立等式:n0 + n1 + n2 = (n1 + 2n2)+ 1 → 化简得 n0 = n2 + 1。
验证:示例二叉树中,n0=3(4、5、6),n2=2(1、2),3=2+1,完全符合。
六、写在最后
从链表(线性单一指向)到二叉树(层级左右分叉),是数据结构从"线性"到"层级"的关键跨越。二叉树的核心价值的在于解决链表"查找效率低"的问题,而n0 = n2 + 1这一性质,是后续学习二叉搜索树、平衡二叉树的基础。
🌱 数据结构的学习,核心是理解"按需设计"的逻辑------每一种结构的升级,都是为了适配更复杂的业务场景。下一篇,我们将拆解二叉树的三种遍历方式,用C++实现递归与非递归代码,敬请期待!
