二叉树的存储方式和遍历方式详解
创作时间:
作者:
@小白创作中心
二叉树的存储方式和遍历方式详解
引用
CSDN
1.
https://blog.csdn.net/qq_51352130/article/details/143312785
二叉树是数据结构中一种重要的树形结构,其存储和遍历方式是算法学习中的基础内容。本文将详细介绍二叉树的两种存储方式(链式存储和顺序存储)以及三种主要的遍历方式(深度优先搜索DFS和广度优先搜索BFS)。通过具体的代码示例,帮助读者深入理解二叉树的存储和遍历方法。
二叉树的存储方式
二叉树的存储方式主要有两种:链式存储和顺序存储。
链式存储
链式存储通过指针将分布在各个地址的节点串联起来。每个节点包含数据域和两个指针域,分别指向其左右子节点。
链式存储的二叉树节点定义方式如下:
public class TreeNode {
int val;
TreeNode left; //表示左子节点的引用,类型为TreeNode
TreeNode right;
TreeNode() {}
TreeNode(int val) {
this.val = val;
}
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
顺序存储
顺序存储是将二叉树的节点按照某种顺序存储在数组中。如果父节点的数组下标是 i,那么它的左孩子就是 2i + 1,右孩子是 2i + 2,孩子的父节点为 (i-1)/2。
二叉树的遍历方式
二叉树的遍历方式主要有两种:深度优先搜索(DFS)和广度优先搜索(BFS)。
深度优先搜索(DFS)
深度优先搜索可以分为前序遍历、中序遍历和后序遍历。每种遍历方式都可以通过递归和迭代两种方法实现。
DFS-递归遍历
前序遍历
前序遍历的顺序是:根节点 -> 左子树 -> 右子树。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
preorder(root, result);
return result;
}
public void preorder(TreeNode root, List<Integer> result) {
if (root == null) {
return;
}
result.add(root.val);
preorder(root.left, result);
preorder(root.right, result);
}
}
中序遍历
中序遍历的顺序是:左子树 -> 根节点 -> 右子树。
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
inorder(root, res);
return res;
}
void inorder(TreeNode root, List<Integer> list) {
if (root == null) {
return;
}
inorder(root.left, list);
list.add(root.val);
inorder(root.right, list);
}
}
后序遍历
后序遍历的顺序是:左子树 -> 右子树 -> 根节点。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
postorder(root, res);
return res;
}
void postorder(TreeNode root, List<Integer> list) {
if (root == null) {
return;
}
postorder(root.left, list);
postorder(root.right, list);
list.add(root.val);
}
}
DFS-迭代遍历
迭代遍历通常使用栈来辅助实现。
前序遍历
前序遍历的顺序是:中-左-右,入栈顺序是:中-右-左。
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
result.add(node.val);
if (node.right != null){
stack.push(node.right);
}
if (node.left != null){
stack.push(node.left);
}
}
return result;
}
}
中序遍历
中序遍历的顺序是:左-中-右,入栈顺序是:左-右。
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while(cur != null || !stack.isEmpty()){
if(cur != null){
stack.push(cur);
cur = cur.left;
}
else{
cur = stack.pop();
result.add(cur.val);
cur = cur.right;
}
}
return result;
}
}
后序遍历
后序遍历的顺序是:左-右-中,可以通过先实现前序遍历(中-右-左),然后反转结果集来实现。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
result.add(node.val);
if (node.left != null){
stack.push(node.left);
}
if (node.right != null){
stack.push(node.right);
}
}
Collections.reverse(result);
return result;
}
}
广度优先搜索(BFS)
广度优先搜索通常用于层次遍历,即按层访问二叉树的节点。
BFS-层次遍历
层次遍历可以使用队列来辅助实现。
迭代方式
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> resList = new ArrayList<>();
if (root == null) {
return resList;
}
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
while(!que.isEmpty()){
List<Integer> itemList = new ArrayList<>();
int levelSize = que.size();
for (int i = 0; i < levelSize; i++) {
TreeNode tmpNode = que.poll();
itemList.add(tmpNode.val);
if(tmpNode.left != null){
que.offer(tmpNode.left);
}
if(tmpNode.right != null){
que.offer(tmpNode.right);
}
}
resList.add(itemList);
}
return resList;
}
}
递归方式
class Solution {
List<List<Integer>> resList = new ArrayList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
checkFun01(root, 0);
return resList;
}
public void checkFun01(TreeNode node, int deep) {
if (node == null) {
return;
}
deep++;
if (resList.size() < deep) {
resList.add(new ArrayList<Integer>());
}
resList.get(deep - 1).add(node.val);
checkFun01(node.left, deep);
checkFun01(node.right, deep);
}
}
对于自底向上的层次遍历,可以在最后将结果集翻转:Collections.reverse(resList);
热门推荐
中产阶层破防,“返贫五件套”个个中招,或将催生新中产涌现?
硕士论文如何撰写开题报告
硅胶如何正确清洗?详细步骤及注意事项有哪些?
洗衣机中途停止打不开,具体原因和解决方法
深度学习:从技术突破到未来展望
新研究:富含植物的“营养饮食”可减缓女性的生物衰老
汽车内饰设计新趋势:雕琢舒适驾驶空间
关关公子五部经典小说盘点:多女主文爱好者的必读佳作
赣江观澜:江西“道教名山”何以唱响“龙虎天下绝”
储藏间如何设计装修
《沙尘暴》7集过后,程春案告破,她的悲剧,恰好是铁锈区悲剧
肋骨里面隐痛有时候会影响呼吸
补胶原蛋白最好的食物有哪些食物
全画幅不是半画幅的两倍?聊聊相机的传感器尺寸
IMDb恐怖片最高分Top10, 鬼店、驚魂記、月光光心慌慌超經典,鬼入侵奪冠
为什么GPU解码被称为硬件解码,而CPU解码是软件解码
如何在家居环境中巧妙挂画,打造个性化空间?
守护“心”健康!心衰患者如何科学“养心”?这份生活指南请收好
如何解读黄金局发布的黄金价值表?这些价值数据对市场分析有何帮助?
双剑合璧:刘备的"武器"如何成为乱世王者之剑?
因货舱受损,NASA 取消“天鹅座”6 月国际空间站货运任务
数控技术:现代制造业的核心技术,其高精度、高效率及发展趋势如何?
宠物美容师:未来就业市场的黄金职业?
少女动画推荐:有哪些经典且必看的少女向动画作品值得收藏?
张雪峰谈制药工程专业就业前景、考研方向、优势与劣势
直播带货欺诈行为认定:法律视角下的实务总结
双子座和摩羯座配吗:两个极端的组合需要奇迹吗?
应对紧张的心理学策略
紫气东来:一个成语背后的文化密码
如何经营小诊所项目管理