
🏠个人主页:黎雁
🎬作者简介:C/C++/JAVA后端开发学习者
❄️个人专栏:C语言、数据结构(C语言)、EasyX、游戏、规划、程序人生
✨ 从来绝巘须孤往,万里同尘即玉京

文章目录
- 二叉树入门全攻略:从树的概念到遍历实现✨
-
- 文章摘要
- [一、知识回顾:线性结构 vs 非线性结构](#一、知识回顾:线性结构 vs 非线性结构)
- 二、树的核心概念:什么是倒挂的树?📚
-
- [1. 树的定义(递归本质)](#1. 树的定义(递归本质))
- [2. 树的关键术语(必须熟记)](#2. 树的关键术语(必须熟记))
- [3. 树的三种表示方式](#3. 树的三种表示方式)
- 三、二叉树的核心知识:最简单的树结构🌿
-
- [1. 二叉树的定义](#1. 二叉树的定义)
- [2. 二叉树的三种遍历方式(分治算法核心)](#2. 二叉树的三种遍历方式(分治算法核心))
- [3. 二叉树遍历的代码实现](#3. 二叉树遍历的代码实现)
- [四、特殊二叉树:满二叉树 vs 完全二叉树🌟](#四、特殊二叉树:满二叉树 vs 完全二叉树🌟)
-
- [1. 满二叉树(装满的二叉树)](#1. 满二叉树(装满的二叉树))
- [2. 完全二叉树(填不满但连续的二叉树)](#2. 完全二叉树(填不满但连续的二叉树))
- 五、二叉树的5个核心性质(必背)📝
- 六、写在最后
二叉树入门全攻略:从树的概念到遍历实现✨
你好!欢迎来到数据结构系列二叉树篇的第一篇内容~
在前面的栈与队列篇中,我们掌握了两种经典的线性结构变种,而今天要解锁的二叉树,是数据结构世界中第一个真正意义上的非线性结构。它打破了线性排列的限制,以分支+层级的形式组织数据,是后续学习平衡树、红黑树、B树等高级数据结构的基础,更是算法面试中的高频考点🌳
准备好了吗?让我们从树的基础概念入手,一步步吃透二叉树的核心知识!🚀
文章摘要
本文为数据结构系列二叉树篇首篇入门内容,系统讲解树与二叉树的核心概念、结构特征及关键术语,重点剖析二叉树前序、中序、后序三种遍历方式的分治思想与代码实现,补充满二叉树、完全二叉树等特殊二叉树的定义与数学性质,结合实例推导二叉树节点数、高度等核心公式,零基础也能吃透二叉树的基础理论与核心操作。
阅读时长 :约25分钟
阅读建议:
- 基础薄弱者:先理解树的递归定义,再掌握二叉树遍历的核心逻辑
- 刷题备考者:重点记忆二叉树的5个核心性质及推导过程
- 面试冲刺者:熟练掌握前/中/后序遍历的递归实现模板
- 查漏补缺者:聚焦满二叉树与完全二叉树的区别及公式推导
一、知识回顾:线性结构 vs 非线性结构
在学习二叉树之前,我们先对比线性结构和非线性结构的核心差异:
| 结构类型 | 核心特征 | 代表结构 | 数据关系 |
|---|---|---|---|
| 线性结构 | 数据呈线性排列,每个元素仅有一个前驱/后继 | 顺序表、链表、栈、队列 | 一对一 |
| 非线性结构 | 数据呈层级/网状排列,元素可有多个前驱/后继 | 树、图 | 一对多(树)/多对多(图) |
简单来说:线性结构是一条线,树结构是一棵树,而二叉树是树结构中最简单、最常用的一种!
二、树的核心概念:什么是倒挂的树?📚
1. 树的定义(递归本质)
树是一种非线性结构,像一棵根朝上、叶朝下的倒挂树,核心特征:
- 有且仅有一个根节点(最顶层的节点);
- 根节点下有若干棵互不相交的子树,子树同样满足树的定义(递归);
- 除根节点外,每个节点有且仅有一个父节点;
- n个节点的树有n-1条边(无环、无孤立节点)。
2. 树的关键术语(必须熟记)
| 术语 | 定义 | 示例 |
|---|---|---|
| 节点的度 | 一个节点包含的子树个数 | 根节点A有6个子节点 → A的度为6 |
| 叶子节点(终端节点) | 度为0的节点(无子女) | B、C、H、I |
| 分支节点(非终端节点) | 度不为0的节点 | D、E、F、G |
| 父/子节点 | 若节点X是Y的子树根,则X是Y的父,Y是X的子 | A是B的父,B是A的子 |
| 兄弟节点 | 具有相同父节点的节点 | B和C是亲兄弟 |
| 树的度 | 树中所有节点的度的最大值 | 树的度=6(A的度) |
| 节点的层次 | 根为第1层,子节点为第2层(推荐方式) | A在第1层,B在第2层 |
| 树的高度(深度) | 树中节点的最大层次 | 若I在第4层 → 树高=4 |
3. 树的三种表示方式
树的存储需要适配一对多的特性,常见三种方式:
| 表示方式 | 核心思路 | 优缺点 |
|---|---|---|
| 顺序存孩子指针 | 直接定义多个孩子指针(child1/child2...) | 优点:简单;缺点:子节点数固定,浪费空间 |
| 左孩子右兄弟(推荐) | 每个节点存左孩子+右兄弟指针 | 优点:适配任意树,空间高效;缺点:需转换思维 |
| 双亲表示法 | 数组存储节点,额外存父节点下标 | 优点:找父节点快;缺点:找子节点慢(并查集专用) |
三、二叉树的核心知识:最简单的树结构🌿
1. 二叉树的定义
二叉树是每个节点最多有2个子节点的树(左子树+右子树),核心特征:
- 二叉树的子树有左右之分,不能颠倒(左子树≠右子树);
- 任何二叉树可拆分为:根节点 + 左子树 + 右子树(分治思想基础);
- 二叉树可以为空(空树也是合法的二叉树)。
2. 二叉树的三种遍历方式(分治算法核心)
遍历是二叉树最核心的操作,本质是分而治之:把遍历整棵树拆成遍历根+左子树+右子树,直到子树为空。
| 遍历方式 | 顺序 | 核心逻辑 | 示例(树:A(B(D,E),C)) |
|---|---|---|---|
| 前序遍历(根左右) | 根 → 左子树 → 右子树 | 先访问根,再递归遍历左右 | 输出:A B D NULL NULL E NULL NULL C NULL NULL(简写ABDEC) |
| 中序遍历(左根右) | 左子树 → 根 → 右子树 | 先遍历左子树,再访问根,最后遍历右 | 输出:NULL D NULL B NULL E NULL A NULL C NULL(简写DBEAC) |
| 后序遍历(左右根) | 左子树 → 右子树 → 根 | 先遍历左右子树,最后访问根 | 输出:NULL NULL D NULL NULL E B NULL NULL C A(简写DEBCA) |
3. 二叉树遍历的代码实现
(1)二叉树节点结构体定义
c
typedef int BTDataType;
typedef struct BinaryTreeNode
{
struct BinaryTreeNode* left; // 左孩子指针
struct BinaryTreeNode* right; // 右孩子指针
BTDataType data; // 节点存储的数据
}BTNode;
(2)前序遍历实现
c
void PreOrder(BTNode* root)
{
if (root == NULL) // 递归终止条件:空节点
{
printf("NULL ");
return;
}
printf("%c ", root->data); // 1. 访问根节点
PreOrder(root->left); // 2. 递归遍历左子树
PreOrder(root->right); // 3. 递归遍历右子树
}
(3)中序遍历实现
c
void InOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
InOrder(root->left); // 1. 递归遍历左子树
printf("%c ", root->data); // 2. 访问根节点
InOrder(root->right); // 3. 递归遍历右子树
}
(4)后序遍历实现
c
void PostOrder(BTNode* root)
{
if (root == NULL)
{
printf("NULL ");
return;
}
PostOrder(root->left); // 1. 递归遍历左子树
PostOrder(root->right); // 2. 递归遍历右子树
printf("%c ", root->data); // 3. 访问根节点
}
💡 核心技巧 :三种遍历的代码仅输出根节点的位置不同,记住这个规律,就能快速写出任意遍历的代码!
四、特殊二叉树:满二叉树 vs 完全二叉树🌟
1. 满二叉树(装满的二叉树)
- 定义:每一层的节点数都达到最大值(第k层有 2 k − 1 2^{k-1} 2k−1个节点);
- 核心公式(根为第1层):
- 高度为h的满二叉树,总节点数: N = 2 h − 1 N = 2^h - 1 N=2h−1;
- 总节点数为N的满二叉树,高度: h = l o g 2 ( N + 1 ) ≈ l o g 2 N h = log_2(N+1) ≈ log_2N h=log2(N+1)≈log2N。
2. 完全二叉树(填不满但连续的二叉树)
- 定义:① 前h-1层是满的;② 最后一层节点从左到右连续排列(无空缺);
- 核心公式(根为第1层):
- 高度为h的完全二叉树,总节点数: 2 h − 1 ≤ N ≤ 2 h − 1 2^{h-1} ≤ N ≤ 2^h - 1 2h−1≤N≤2h−1;
- 总节点数为N的完全二叉树,高度: l o g 2 ( N + 1 ) ≤ h ≤ l o g 2 N + 1 log_2(N+1) ≤ h ≤ log_2N + 1 log2(N+1)≤h≤log2N+1。
✅ 关键区别:
- 满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树;
- 完全二叉树的最后一层靠左连续,这是和普通二叉树的核心区别。
五、二叉树的5个核心性质(必背)📝
- 第n层最多有 2 n − 1 2^{n-1} 2n−1个节点(根为第1层);
- 高度为h的二叉树,最大节点数为 2 h − 1 2^h - 1 2h−1;
- 任意二叉树:叶子节点数n_0 = 度为 2 的节点数 度为2的节点数 度为2的节点数n_2 + 1 ( ( (n_0 = n_2 + 1);
- 满二叉树: N = 2 h − 1 N = 2^h - 1 N=2h−1, h = l o g 2 ( N + 1 ) h = log_2(N+1) h=log2(N+1);
- 完全二叉树: 2 h − 1 ≤ N ≤ 2 h − 1 2^{h-1} ≤ N ≤ 2^h - 1 2h−1≤N≤2h−1。
性质3推导(重中之重):
设度为0/1/2的节点数为 n 0 / n 1 / n 2 n_0/n_1/n_2 n0/n1/n2,总结点数 N = n 0 + n 1 + n 2 N = n_0 + n_1 + n_2 N=n0+n1+n2;
总边数 E = n 1 + 2 n 2 E = n_1 + 2n_2 E=n1+2n2(度为1的节点出1条边,度为2的出2条);
又因为 E = N − 1 E = N - 1 E=N−1(除根外,每个节点有1条入边);
联立得: n 0 + n 1 + n 2 − 1 = n 1 + 2 n 2 n_0 + n_1 + n_2 - 1 = n_1 + 2n_2 n0+n1+n2−1=n1+2n2 → 化简得 n 0 = n 2 + 1 n_0 = n_2 + 1 n0=n2+1。
六、写在最后
恭喜你!在这一篇中,你已经掌握了二叉树的核心基础:
- 理解了树的递归定义和关键术语;
- 掌握了二叉树前/中/后序遍历的递归实现;
- 区分了满二叉树和完全二叉树,记住了核心公式;
- 推导并熟记了二叉树的5个核心性质。
二叉树的遍历是所有树结构操作的基础,建议你多敲几遍遍历代码,用纸笔模拟遍历过程------只有真正理解分治思想,才能搞定后续的层序遍历、节点计数、OJ刷题等进阶内容。
下一篇,我们将进入二叉树的实战环节:学习层序遍历、节点计数、平衡二叉树判断等核心操作,把理论转化为解题能力!😜
点赞+收藏+关注,跟着系列内容一步步吃透二叉树!你的支持是我创作的最大动力~👍