二叉树的基本数据结构

简介: 二叉树是最基础且最重要的数据结构,不仅是红黑树、堆、字典树等的构建基础,更体现了递归思维,是理解回溯、动态规划等算法的关键。掌握二叉树,等于掌握算法核心逻辑。

我认为二叉树是最重要的基本数据结构,没有之一。
如果你是初学者,现在这个阶段我很难给你彻底解释清楚得出这个结论的原因,你需要认真学习本站后面的内容才能逐渐理解。我暂且总结两个点:
1、二叉树本身是比较简单的基础数据结构,但是很多复杂的数据结构都是基于二叉树的,比如 红黑树(二叉搜索树)、多叉树、二叉堆、图、字典树、并查集、线段树 等等。你把二叉树玩明白了,这些数据结构都不是问题;如果你不把二叉树搞明白,这些高级数据结构你也很难驾驭。
2、二叉树不单纯是一种数据结构,更代表着递归的思维方式。一切递归算法,比如 回溯算法、BFS 算法、动态规划 本质上也是把具体问题抽象成树结构,你只要抽象出来了,这些问题最终都回归二叉树的问题。同样看一段算法代码,在别人眼里是一串文本,每个字都认识,但连起来就不认识了;而在你眼里的代码就是一棵树,想咋改就咋改,咋改都能改对,实在是太简单了。
后面的数据结构章节包含大量关于二叉树的讲解和习题,你按照本站的目录顺序学习,我会带你把二叉树彻底搞懂,到时候你就明白我为什么这么重视二叉树了。
几种常见的二叉树
二叉树的主要难点在于做算法题,它本身其实没啥难的,就是这样一种树形结构嘛:
1
/ \
2 3
/ / \
4 5 6
/ \
7 8
上面就是一棵普通的二叉树,几个术语你要了解一下:
1、每个节点下方直接相连的节点称为子节点,上方直接相连的节点称为父节点。比方说节点 3 的父节点是 1,左子节点是 5,右子节点是 6;节点 5 的父节点是 3,左子节点是 7,没有右子节点。
2、我们称最上方那个没有父节点的节点 1 为根节点,称最下层没有子节点的节点 4、7、8 为叶子节点。
3、我们称从根节点到最下方叶子节点经过的节点个数为二叉树的最大深度/高度,上面这棵树的最大深度是 4,即从根节点 1 到叶子节点 7 或 8 的路径上的节点个数。
没啥别的可说的了,就是这么简单。有一些稍微特殊一些的二叉树,有他们自己的名字,你要了解一下,后面做题时见到这些专业术语,你就知道题目在说啥了。
满二叉树
直接看图比较直观,满二叉树就是每一层节点都是满的,整棵树像一个正三角形:

满二叉树有个优势,就是它的节点个数很好算。假设深度为 h,那么总节点数就是 2^h - 1,等比数列求和嘛,我们应该都学过的。
完全二叉树
完全二叉树指:二叉树每一层节点都紧凑靠左排列,且除了最后一层,其他每层都必须是满的:

不难发现,满二叉树其实是一种特殊的完全二叉树。完全二叉树的特点:由于它的节点紧凑排列,如果从左到右从上到下对它的每个节点编号,那么父子节点的索引存在明显的规律。
完全二叉树还有个比较难发觉的性质:完全二叉树的左右子树也是完全二叉树。或者更准确地说应该是:完全二叉树的左右子树中,至少有一棵是满二叉树

二叉搜索树
二叉搜索树(Binary Search Tree,简称 BST)是一种很常见的二叉树,它的定义是:对于树中的每个节点,其左子树的每个节点的值都要小于这个节点的值,右子树的每个节点的值都要大于这个节点的值。你可以简单记为「左小右大」。我把「子树的每个节点」加粗了,这是初学者常犯的错误,不要只看子节点,而要看整棵子树的所有节点。比方说,下面这棵树就是一棵 BST:
7
/ \
4 9
/ \ \
1 5 10
节点 7 的左子树所有节点的值都小于 7,右子树所有节点的值都大于 7;节点 4 的左子树所有节点的值都小于 4,右子树所有节点的值都大于 4,以此类推。下面这棵树就不是 BST:
7
/ \
4 9
/ \ \
1 8 10
如果你只注意每个节点的左右子节点,似乎看不出问题。你应该看整棵子树,注意看节点 7 的左子树中有个节点 8,比 7 大,这就不符合 BST 的定义了。
BST 是非常常用的数据结构。因为左小右大的特性,可以让我们在 BST 中快速找到某个节点,或者找到某个范围内的所有节点,这是 BST 的优势所在。
比方说,对于一棵普通的二叉树,其中的节点大小没有任何规律可言,那么你要找到某个值为 x 的节点,只能从根节点开始遍历整棵树。而对于 BST,你可以先对比根节点和 x 的大小关系,如果 x 比根节点大,那么根节点的整棵左子树就可以直接排除了,直接从右子树开始找,这样就可以快速定位到值为 x 的那个节点。
关于 BST,后面会专门章节详解,并且配有大量的习题,这里先讲些基础概念就够你用了。
二叉树的实现方式
最常见的二叉树就是类似链表那样的链式存储结构,每个二叉树节点有指向左右子节点的指针,这种方式比较简单直观。力扣/LeetCode 上给你输入的二叉树一般都是用这种方式构建的,二叉树节点类 TreeNode 一般长这样:
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { this.val = x; }
}

// 你可以这样构建一棵二叉树:
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.right.left = new TreeNode(5);
root.right.right = new TreeNode(6);

// 构建出来的二叉树是这样的:
// 1
// / \
// 2 3
// / / \
// 4 5 6
另外,在一般的算法题中,我们可能会把实际问题抽象成二叉树结构,但我们并不需要真的用 TreeNode 创建一棵二叉树出来,而是直接用类似 哈希表 的结构来表示二叉树/多叉树。比方说上面那棵二叉树
1
/ \
2 3
/ / \
4 5 6
我可以用一个哈希表,其中的键是父节点 id,值是子节点 id 的列表(每个节点的 id 是唯一的),那么一个键值对就是一个多叉树节点了,这棵多叉树就可以表示成这样:
// 1 -> [2, 3]
// 2 -> [4]
// 3 -> [5, 6]

HashMap> tree = new HashMap<>();
tree.put(1, Arrays.asList(2, 3));
tree.put(2, Collections.singletonList(4));
tree.put(3, Arrays.asList(5, 6));
这样就可以模拟和操作二叉树/多叉树结构,后文讲到图论的时候你就会知道,它有一个新的名字叫做 邻接表。

相关文章
|
20小时前
|
机器学习/深度学习 人工智能 自然语言处理
Chap01. 认识AI
本文介绍AI核心概念与大模型开发原理,涵盖人工智能发展历程及Transformer神经网络的关键作用。通过注意力机制,Transformer实现对文本、图像、音频的高效处理,成为GPT等大模型的基础。大语言模型(LLM)利用其持续生成能力,逐字预测输出,实现连贯对话。
|
17小时前
|
域名解析 缓存 网络协议
网络优化方案
通过合并压缩资源、合理缓存、DNS预解析、CDN加速、预加载与预渲染、图片优化等手段,减少HTTP请求、提升加载速度。利用hash值更新缓存,结合雪碧图、WebP格式及骨架屏,显著改善页面性能与用户体验,有效降低首屏加载时间。
|
17小时前
|
JavaScript
虚拟滚动技术
插入几万个DOM时,为避免页面卡顿,可采用虚拟滚动技术,仅渲染可视区域内的元素,滚动时动态更新内容,大幅减少DOM数量。相比requestAnimationFrame分批插入,虚拟滚动性能更优,推荐使用react-virtualized等库实现,有效提升渲染效率。(238字)
|
17小时前
|
缓存 监控 JavaScript
前端性能监控指标
前端性能指标包括白屏时间、首屏时间、DOM可操作时间和页面总加载时间。可通过注入代码或`window.performance` API进行量化统计,后者基于浏览器标准接口,提供精确的网络、解析与渲染各阶段耗时数据,助力性能优化。
|
18小时前
|
安全
CSRF攻击
CSRF(跨站请求伪造)攻击利用用户已登录身份,诱导其触发恶意请求,窃取资金或冒用权限。防御措施包括:使用Token验证、SameSite Cookie、检查Referer、禁止第三方携带Cookie,并在关键操作中添加验证码,有效防止非法请求。
|
17小时前
|
缓存 JavaScript 前端开发
重绘回流过程
浏览器渲染流程:解析HTML生成DOM树,CSS生成CSSOM,合并为渲染树,再布局、绘制。DOM树包含所有元素,渲染树仅含可见节点。CSS阻塞渲染但不阻塞DOM解析。重绘因样式变化,回流因布局变化,回流必触发重绘。减少回流重绘可提升性能。
|
17小时前
|
JavaScript 前端开发 测试技术
Angular框架
本文深入解析Angular核心概念,涵盖ng-show与ng-if的性能差异、$rootScope与$scope的关系、表达式机制、Digest周期、定时器与监听器的取消方法。同时探讨Directive的restrict属性、作用域绑定方式及模块间通信策略。此外,介绍性能优化技巧、单元测试实践、Angular 2生命周期钩子、路由机制、事件发射器、AOT编译、安全防护与Shadow DOM等高级主题,全面提升开发技能。
|
17小时前
|
缓存
浏览器缓存
HTTP缓存通过Cache-Control和ETag实现。Cache-Control控制缓存行为,如public/private、no-cache/no-store,以及max-age等时效与验证机制;ETag则用于对比资源是否变更,配合If-None-Match实现304协商缓存。结合内容哈希文件名可优化静态资源更新策略,确保用户获取最新版本。
|
17小时前
|
域名解析 缓存 边缘计算
CDN加速
CDN(内容分发网络)通过在全球部署节点服务器,将源站内容缓存至边缘节点,用户访问时由最近节点提供服务。基于DNS重定向与智能调度,实现就近加速,降低延迟,提升访问速度与网站可用性,有效应对高并发、带宽不足等问题。
|
17小时前
|
存储 JavaScript 前端开发
XSS攻击
XSS(跨站脚本攻击)是攻击者通过网站漏洞注入恶意脚本,用户访问时执行,窃取数据、Cookie或劫持会话。主要分反射型和存储型,危害大。防御措施包括输入转义、白名单过滤及CSP内容安全策略,有效防止脚本注入。