当前位置: 首页 > news >正文

二叉树的递归层序遍历

二叉树的递归/层序遍历

1. 递归遍历(DFS)

递归遍历二叉树的代码如下:

class TreeNode {int val;TreeNode left, right;
}public void traverse(TreeNode root) {if (root == null) {return;}// 进行遍历traverse(root.left);traverse(root.right);
}

traverse 函数的遍历顺序,就是一直往左节点走,左节点走不下去了,再往右节点走,然后又开始往左节点走,循环往复,直到左右节点都遍历完了,就返回父节点。看代码也能看出来,先调用 root.left,再调用 root.right,一定是先往左节点走,碰到 null 才开始往右节点走一次

只要遵循先左再右的规则,traverse 函数访问节点的顺序就是固定的,插入多少条数据都不会发生变化。那有人问了,为什么之前学的数据结构会分为,前序遍历、中序遍历、后序遍历等不同的方式,这是为什么?

所谓的前序遍历这些方式,指的是在不同的时机将对节点进行操作(例如打印节点)。

public void traverse(TreeNode root) {if (root == null) {return;}//前序遍历traverse(root.left);// 中序遍历traverse(root.right);// 后序遍历
}

前序位置的代码会在进入节点时立即执行;中序位置的代码会在左子树遍历完成后,遍历右子树之前执行;后序位置的代码会在左右子树遍历完成后执行

特别强调,三种位置的不同关键是操作的时机不同,而二叉树遍历的的轨迹不会发生变化(先左再右)。在实际的算法题中,不会要求你写前中后序遍历的,关键在于把正确的代码写到正确的位置。

2. 层序遍历(BFS)

层序遍历,顾名思义,一层一层的进行遍历,从上到下,从左到右。层序遍历需要依赖队列来实现,可以分为三种方式来实现。补个关于队列的 API 的小知识点:

  • add(E e):向队尾添加元素;队列满时抛异常
  • offer(E e):向队尾添加元素;队列满时返回 false(不抛异常)。
  • remove():移除并返回队头元素;队列空时抛异常
  • poll():移除并返回队头元素;队列空时返回 null(不抛异常)。
  • element():返回队头元素(不移除);队列空时抛异常
  • peek():返回队头元素(不移除);队列空时返回 null

写法一

public void levelOrderTraverse(TreeNode root) {if (root == null) {return;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {// 开始将头部的元素移除TreeNode cur = queue.poll();System.out.println(cur.val);// 随后将 cur 的左右节点放到队列中if (cur.left != null) {q.offer(cur.left);}if (cur.right != null) {q.offer(cur.right);}}
}

这种写法是最简单的,每次先将队头元素取出来,再将其左右节点放到队列尾部,就成了,但是缺点也明显,无法得知当前节点的在哪一层,这个需求挺常见的,比如:收集某一层的节点,或者找出二叉树的最小深度等等。

写法二

public void levelOrderTraverse(TreeNode root) {if (root == null) {return;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);// 记录当前遍历到的层数(根节点视为第 1 层)int depth = 1;while (!queue.isEmpty()) {// 可以使用一个 size() 方法,得知当前队列内有多少元素,这些元素都在一层的int sz = queue.size();for (int i = 0; i < sz; i++) {TreeNode cur = queue.poll();// 访问 cur 节点,同时打印 cur 所在的位置(哪一层depth)System.out.println("depth = " + depth + ", val = " + cur.val);// 将 cur 的左右节点放到队尾if (cur.left != null) {queue.offer(cur.left);}if (cur.right != null) {queue.offer(cur.right);}}depth++;}
}

这种写法就可以记录下来每个节点所在的层数,可以解决诸如二叉树最小深度这样的问题,是我们最常用的层序遍历写法。

写法三

回顾一下写法二,每往下走一层,depth 进行+1操作,是不是可以理解为每条树枝的权重是1,二叉树的每个节点是不是可以理解为:根节点到该节点的路径权重和,但是吧,同一层的节点,它们的路径权重和是不是一样的?

那么假设,每个节点的路径权重和是任意数,让你层序遍历每个节点,打印其的路径权重和,你会怎么办?那么,每一层的节点的路径权重和就和之前不一样了,写法二这种只使用一个 depth 变量就无法满足需求了。

写法三就是为了解决这个问题,在方法一的基础上写一个 State 类,让每个节点自己负责维护自身的路径权重。

class State {TreeNode node;int depth;State(TreeNode node, int depth) {this.node = node;this.depth = depth;}
}public void levelOrderTarverse(TreeNode root) {if (root == null) {return;}Queue<State> queue = new LinkedList<>();// 根节点的路径权重和是 1queue.offer(new State(root, 1));while (!queue.isEmpty()) {State cur = queue.poll();// 再访问 cur 节点的同时,打印其权重路径和 System.out.println("depth:" + cur.depth + ",val = " + cur.node.val);// 再将 cur 左右节点放到队尾中if (cur.node.left != null) {queue.offer(new State(cur.node.left, cur.depth + 1));}if (cur.node.right != null) {queue.offer(new State(cur.node.right, cjur.depth + 1));}}
}

这样每个节点都有了自己的 depth 变量,是最灵活的,可以满足所有 BFS 算法的需求。但是由于要额外定义一个 State 类比较麻烦,所以非必要的话,用写法二就够了。

接下来,你就可以无痛完成下面这几道题了

力扣难度
102. 二叉树的层序遍历🟠
144. 二叉树的前序遍历🟢
145. 二叉树的后序遍历🟢
94. 二叉树的中序遍历🟢
http://www.dtcms.com/a/430887.html

相关文章:

  • 牛客算法基础noob58 无限长正整数排列字符串
  • ECharts 配置语法详解
  • 哪个网站做自媒体比较好华为网站建设的目标是否明确
  • 【机器学习】 在Jupyter Notebook 中如何指定Python环境
  • springboot海洋馆预约系统的设计与实现(代码+数据库+LW)
  • 精通C语言(1.内存函数)
  • Radio Garden官网入口 - 全球广播电台在线收听网站|网页版|打不开
  • 基于以太坊的Dao治理系统
  • 【LeetCode_203】移除链表元素
  • LeetCode刷题记录----75.颜色分类
  • QQ可以在网站做临时会话么温州的网站建设公司
  • Java-Spring 入门指南(十七)SpringMVC--Apipostl与RestFul实战测试
  • Codeforces Round 993A Easy Problem
  • OSI模型、网络地址、与协议
  • Codeforces Round 993B. Normal Problem
  • 《嵌入式 – GD32开发实战指南(RISC-V版本)》第3章 GPIO流水灯的前世今生
  • 深圳手机网站建设哪家好表白链接生成器
  • GameObject 常见类型详解 -- 光环生成对象(AURA GENERATOR)
  • 29.CSS 3D 加载转轮 | CSS 动画效果
  • 潍坊制作网站用淘宝做公司网站
  • AMQP协议深度解析:消息队列背后的通信魔法
  • CSP-J/S复赛真实考试场景还原与备考策略
  • 攻防世界-Web-inget
  • flex布局学习记录
  • unordered_map和unordered_set的使用以及哈希表的实现
  • Powershell 管理 后台/计划 作业(六)
  • 北京网站建设公司东为企业网络营销方案策划书
  • 四川网站营销seo什么价格网站建设哪家g
  • k8s-pod的镜像升级与回滚
  • Django 从入门到进阶:构建完整的博客系统