二叉树的五种遍历方法
1. 概述
遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个结点转换成为一个线性序列来表示。
2. 二叉树的五种遍历方法
首先要知道,不管是哪种遍历方法,都是左子树在右子树的前面,只是根的位置不同。
- 前根遍历
- 中根遍历
- 后根遍历
- 广度优先遍历
- 深度优先遍历
3. 先序遍历/深度优先遍历
首先访问根,再先序遍历左(右)子树,最后先序遍历右(左)子树。
前根遍历实际上就是深度优先遍历
3-1. 递归遍历
/**
* 前根遍历 先打印根 根 - 左 - 右
* @param root 树根
*/
private static void prefixLoop(TreeNode root) {
// 递归终止条件
if (root == null)
return;
// 输出 根
System.out.print(root.value + " ");
// 向左遍历
prefixLoop(root.left);
// 向右遍历
prefixLoop(root.right);
}
3-2. 迭代遍历
/**
* 深度优先
* @param root 树根
*/
private static void depthFirst(TreeNode root) {
// 定义临时栈
ArrayDeque<TreeNode> stack = new ArrayDeque<>();
// 将根节点添加到栈中
stack.addLast(root);
while (!stack.isEmpty()) {
TreeNode node = stack.removeLast();
// 输出 根
System.out.print(node.value + " ");
// 先遍历右子树(栈: LILO)
if (node.right != null) {
stack.addLast(node.right);
}
// 后遍历左子树
if (node.left != null) {
stack.addLast(node.left);
}
}
}
4. 中序遍历
首先中序遍历左(右)子树,再访问根,最后中序遍历右(左)子树。
/**
* 中序遍历 中间是根 左 - 根 - 右
* @param root 树根
*/
private static void infixLoop(TreeNode root) {
// 递归终止条件
if (root == null)
return;
// 向左遍历
infixLoop(root.left);
// 输出 根
System.out.print(root.value + " ");
// 向右遍历
infixLoop(root.right);
}
5. 后序遍历
首先后序遍历左(右)子树,再后序遍历右(左)子树,最后访问根。
/**
* 后根遍历 最后是根 左 - 右 - 根
* @param root 树根
*/
private static void subfixLoop(TreeNode root) {
// 递归终止条件
if (root == null)
return;
// 向左遍历
subfixLoop(root.left);
// 向右遍历
subfixLoop(root.right);
// 输出 根
System.out.print(root.value + " ");
}
6. 广度优先遍历
即按照层次访问,通常用队列来做。访问根,访问子女,再访问子女的子女(越往后的层次越低)(两个子女的级别相同)。
/**
* 广度优先遍历
* @param root 树根
*/
private static void breadthFirst(TreeNode root) {
// 定义队列
ArrayDeque<TreeNode> queue = new ArrayDeque<>();
// 添加 根 到队列中
queue.addLast(root);
while (!queue.isEmpty()) {
TreeNode node = queue.removeFirst();
// 输出 根
System.out.print(node.value + " ");
// 添加左子树到队列( 队列: LIFO )
if (node.left != null) {
queue.addLast(node.left);
}
// 添加右子树到队列
if (node.right != null) {
queue.addLast(node.right);
}
}
}
------------------------------我是博客签名------------------------------
座右铭:不要因为知识简单就忽略,不积跬步无以至千里。
版权声明:自由转载-非商用-非衍生-保持署名。
本作品采用知识共享署名 4.0 国际许可协议进行许可。
----------------------------------------------------------------------
座右铭:不要因为知识简单就忽略,不积跬步无以至千里。
版权声明:自由转载-非商用-非衍生-保持署名。
本作品采用知识共享署名 4.0 国际许可协议进行许可。
----------------------------------------------------------------------
分类:
算法题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构