当前位置:网站首页>二叉树的遍历:递归法/ 迭代法/ 统一迭代法(强QAQ)
二叉树的遍历:递归法/ 迭代法/ 统一迭代法(强QAQ)
2022-08-02 14:10:00 【鱼子酱:P】
最近刷题刷到二叉树...算法面试的常客,数据结构基石...
见到许多厉害的解法,膜拜啊~
特此记录一下2022/3/24
力扣对应题目:144,145,94
一:递归法
一看就会,一写就废!~简单解法
前序遍历:
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); // 注意这一句
}
}二:迭代法
递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。so 可以用栈!
前序遍历:
// 前序遍历顺序:中-左-右,入栈顺序:中-右-左
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;
}
}中序遍历:
lass Solution {
public List<Integer> inorderTraversal(TreeNode root) {
//中序遍历:左中右 入栈顺序:左右
List<Integer> result = new ArrayList<>();
if (root == null){
return result;
}
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()){
if (cur != null){
stack.push(cur);//头结点入栈
cur = cur.left;//一直遍历放左节点,到最左的叶子结点,然后到else取出最左的结点,然后放右结点。左边-中间-右边
}else{
cur = stack.pop();
result.add(cur.val);
cur = cur.right;
}
}
return result;
}
}后续遍历:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
//左右中 入栈顺序:中左右 出栈顺序:中右左 翻转:左右中
List<Integer> res = new ArrayList<>();
if(root == null){
return res;
}
Stack<TreeNode> stack1 = new Stack<>();
stack1.push(root);//头结点入栈
while(!stack1.isEmpty()){
TreeNode node = stack1.pop();
res.add(node.val);
if(node.left != null){
stack1.push(node.left);
}
if(node.right != null){
stack1.push(node.right);
}
}
Collections.reverse(res);
return res;
}
}三:统一迭代法
迭代法实现的先中后序,其实风格也不是那么统一,除了先序和后序,有关联,中序完全就是另一个风格了,一会用栈遍历,一会又用指针来遍历。
其实针对三种遍历方式,使用迭代法是可以写出统一风格的代码!
重头戏来了,接下来介绍一下统一写法。
用栈的话,无法同时解决访问节点(遍历节点)和处理节点(将元素放进结果集)不一致的情况。那我们就将访问的节点放入栈中,把要处理的节点也放入栈中但是要做标记。如何标记呢,就是要处理的节点放入栈之后,紧接着放入一个空指针作为标记。 这种方法也可以叫做标记法。
前序遍历:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
//前序:中左右 入栈顺序:右左中
List<Integer> res = new ArrayList<>();//LinkedList也可以
Stack<TreeNode> st = new Stack<>();
if(root != null) st.push(root);
while(!st.empty()){
TreeNode node = st.peek();
if(node != null){
st.pop();//把该节点弹出,避免重复操作
if(node.right != null) st.push(node.right);
if(node.left != null) st.push(node.left);
st.push(node);
st.push(null);//中间结点访问过,但还没有处理,加入空节点标记
}else{
st.pop();//弹出空节点
node = st.pop();//取出被标记的结点
res.add(node.val);//加入res中
}
}
return res;
}
}中序遍历:

后续遍历:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
//后序:左右中 入栈顺序:中右左
List<Integer> res = new LinkedList<>();
Stack<TreeNode> st = new Stack<>();
if(root != null ) st.push(root);
while(!st.empty()){
TreeNode node = st.peek();
if(node != null){
st.pop();//弹出该节点,避免重复
st.push(node);
st.push(null);//中方结点访问过,没处理,标记
if(node.right != null) st.push(node.right);
if(node.left != null) st.push(node.left);
}else{
st.pop();//把null结点弹出
node = st.pop();
res.add(node.val);
}
}
return res;
}
}边栏推荐
猜你喜欢

word方框怎么打勾?

Mysql之MVCC

How to reinstall Win7 system with U disk?How to reinstall win7 using u disk?

Summarize computer network super comprehensive test questions

What should I do if I install a solid-state drive in Win10 and still have obvious lags?

二叉树创建之层次法入门详解

如何用硬币模拟1/3的概率,以及任意概率?

Win10 cannot directly use photo viewer to open the picture

Configure clangd for vscode

镜像法求解接地导体空腔电势分布问题
随机推荐
Installation and configuration of Spark and related ecological components - quick recall
Win10上帝模式干嘛的?Win10怎么开启上帝模式?
质数相关问题-小记
Letter combination of LeetCode2 phone number
Mysql连接错误解决
Summarize computer network super comprehensive test questions
Win10 Settings screen out from lack of sleep?Win10 set the method that never sleep
用U盘怎么重装Win7系统?如何使用u盘重装系统win7?
GMP scheduling model of golang
How to reinstall Win7 system with U disk?How to reinstall win7 using u disk?
实战美团Nuxt +Vue全家桶,服务端渲染,邮箱验证,passport鉴权服务,地图API引用,mongodb,redis等技术点
Win10 computer can't read U disk?Don't recognize U disk how to solve?
DP1332E刷卡芯片支持NFC内置mcu智能楼宇/终端poss机/智能门锁
yolov5官方代码解读——前向传播
SQL的通用语法和使用说明(图文)
MATLAB绘图命令fimplicit绘制隐函数图形入门详解
The SSE instructions into ARM NEON
发布模块到npm应该怎么操作?及错误问题解决方案
Failed to install using npx -p @storybook/cli sb init, build a dedicated storybook by hand
Win11电脑一段时间不操作就断网怎么解决