二叉树的存储方式和遍历方式详解
创作时间:
作者:
@小白创作中心
二叉树的存储方式和遍历方式详解
引用
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);
热门推荐
咸丰旅游全攻略:四季气候与最佳游玩时间
老君山停车场使用攻略:停车位置、充电桩分布及游览建议
陶帅新剧《春花焰》:一段充满悬疑与情感的古装传奇
陶亮:从《西虹市首富》到《这家伙不赖》,演艺路上的突破与成长
鄂温克族:生活在大山林中的人们
婴儿频繁打嗝有妙招,通过推拿、按压等手法最快止嗝
婴儿打嗝最快方法止嗝,通过推拿、按压等手法最快止嗝
北海赶海时间和最佳赶海时间
如何给予下属和团队反馈
西安钟楼拍照攻略:如何拍出绝美大片?
西安钟楼:六百年风雨中的时间守护者
西安钟楼打卡攻略:从古迹到美食
Biotest Pentaglobin:富含IgM的创新免疫球蛋白制剂
免疫球蛋白:守护健康的隐形卫士
Behring:免疫球蛋白的诺奖传奇
喝牛奶吃鸡蛋,轻松提升免疫力!
保持内心宁静以应对生活挑战,追求远大目标的智慧之道
造词技能点拉满的军事家韩信:35年的传奇人生,创造了近30个成语
厦门飞往台北,直线距离或仅仅350公里,却为何要绕行898公里
大陆到台湾多少公里?一海之隔究竟多远?精准揭秘两岸距离全攻略
“刷医保买手表”引热议!从“为疾病买单”到“为健康管理买单”,怎么看?
是存钱好还是交社保好
书法史上的碑帖之争
王羲之《太上玄元道德经册》:书圣晚年小楷精品
什么是职业健康保障
母亲节特辑:伟大而慈爱的母亲
一位艺术妈妈的育儿经:用细节点亮生活
番茄红素:从餐桌到健康的秘密武器
低卡又营养!西红柿减肥新宠
从《嫡嫁千金》薛芳菲看现代职场人的智慧与成长