【算法集训】Java实现之二叉树先中后序遍历、层序遍历、最大深度和合并二叉树

本文是未来村村长的【AlgorithmDay】系列文章,重点讲解了二叉树的先序、中序、后序遍历,层序遍历,最大深度计算以及合并二叉树的算法实现,旨在通过刷题和总结提升逻辑思维和解题能力。文中提供了详细的Java代码实现,并对相关知识点进行了补充,包括递归和树的遍历策略。
摘要由CSDN通过智能技术生成

大家好!我是未来村村长,就是那个“请你跟我这样做,我就跟你这样做!”的村长👨‍🌾!

||Algorithm Day||

​ 未来村村长正推出一系列【Algorithm Day】文章,该系列文章重在提高本人的算法能力,希望能在刷题过程中总结一般方法,提高个人的逻辑思维能力和解题能力。该系列文章以天数为轴,从一个个算法中逐步强化算法相关知识点。

​ ”算法之路,任重而道远。“🌱|day 6|🌾


[声明:以下题目的内容或部分解法来自牛客网或Leetcode,为个人学习总结和记录,也方便大家学习和查阅]

一、二叉树先中后序遍历

1、题目描述

(1)描述

给定一棵二叉树,分别按照二叉树先序,中序和后序打印所有的节点。

(2)示例

在这里插入图片描述

2、思路分析

​ 前中后序遍历在代码实现上相似,都使用了递归的方法,递归方法比较基础,建议《全文背诵》。

3、Java实现

import java.util.*;

public class Solution {
    public int[][] threeOrders (TreeNode root) {
        //建立三个ArrayList作为装载容器
        Lsit<Integer> prelist = new ArrayList<>();
        Lsit<Integer> inlist = new ArrayList<>();
        Lsit<Integer> postlist = new ArrayList<>();
        
        //调用相关遍历方法
        preOrder(list,root);
        inOrder(list,root);
        postOrder(list,root);
        
        //建立结果集返回结果
        int res[][] = new int[3][prelist.size()];
        for(int i = 0;i<prelist.size();i++){
            res[0][i] = prelist.get(i);
            res[1][i] = inlist.get(i);
            res[2][i] = postlist.get(i);
        }
        return res;
    }
    
    //前序遍历方法
    public static void preOrder(List list,ListNode root){
        //凡是递归都要记得return
        if(root == null) return;
    	list.add(root.val);
        preOrder(list,root.left);
        preOrder(list,root.right);
    }
    
    //中序遍历方法
    public static void inOrder(List list,ListNode root){
        //凡是递归都要记得return
        if(root == null) return;
    	list.add(root.val);
        inOrder(list,root.left);
        inOrder(list,root.right);
    }
    
    //后序遍历方法
    public static void postOrder(List list,ListNode root){
        //凡是递归都要记得return
        if(root == null) return;
    	list.add(root.val);
        postOrder(list,root.left);
        postOrder(list,root.right);
    }
    
}

4、相关知识补充

​ 树的先中后序遍历是数据结构常考知识点,一般在选择题出现,给你一个先序后序,让你求个中序啥的,要记住不管是中序还是后序,都是先左再右,变的只是中间节点(双亲节点的输出位置)。

二、二叉树层序遍历

1、题目描述

(1)描述

给定一个二叉树,返回该二叉树层序遍历的结果,(从左到右,一层一层地遍历)

(2)示例

在这里插入图片描述

2、思路分析

​ 利用队列的先进先出进行层序遍历,因为层序遍历的顺序就是从根结点开始逐层从左到右进行遍历输出,我们需要按如下顺序将树节点加入到队列中:

  • 队列先加入根节点
  • 取出根节点,将根节点的val放到list中
  • 如果根节点有左子节点,队列加入左子节点
  • 如果根节点有右子节点,队列加入右子节点
  • 将队列的第一个节点视为根节点,继续执行

3、Java实现

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        //建立结果集
        ArrayList<ArrayList<Integer>> res = new ArrayList();
        //错误判断
        if(root == null) return res;
        //建立一个队列
        Queue<TreeNode> queue = new ArrayDeque<>();
        //先加入头节点
        queue.add(root);
        //迭代
        while(!queue.isEmpty()){
            //建立容器装载每一层的结果
            ArrayList<Integer> row = new ArrayList<>();
            //queue的大小
            int size = queue.size();//有几个就输出几个
            for(int i=0;i<size;i++){
                TreeNode cur = queue.poll();//取出队列的头节点
                row.add(cur.val);//加入到row中
                if(cur.left!=null) queue.add(cur.left);
                if(cur.right!=null) queue.add(cur.right);
            }
            res.add(row);
        }
        return res;
    }
}

4、相关知识补充

​ 树的层序遍历又叫做树的广度优先遍历(BFS),即从上往下逐层从左往右遍历,推荐使用上述的队列实现。

三、二叉树的最大深度

1、题目描述

(1)描述

求给定二叉树的最大深度,

深度是指树的根节点到任一叶子节点路径上节点的数量。

最大深度是所有叶子节点的深度的最大值。

(2)示例

在这里插入图片描述

2、思路分析

如下图(来源牛客网)所示:

​ 因为是二叉树,我们可以从两边进行递归,直到叶子节点时,开始进行返回。每返回一层我们就进行加1,并比较左右两边子树的大小,返回较大值到上一层,最终可以获得最大深度。该递归的三要素为:

  • 终止条件:当节点为null时,返回0
  • 返回值:返回左右子树的深度的较大值
  • 每级任务:向下遍历左右子树

alt

3、Java实现

public class Solution {
    public int maxDepth (TreeNode root) {
        if(root==null) return 0;
        return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
    }
}

4、相关知识补充

(1)递归相关

使用递归我们要考虑以下三个要素:

  • 终止条件:即什么时候开始返回到上一层
  • 返回值:返回什么样的结果(递归如何执行)
  • 每级任务:每层递归要做点什么,才开始进入下一级递归
(2)树的深度优先遍历

​ 这题是取到最大深度采用了深度优先遍历的思想,深度优先遍历的代码如下

private void dfs(TreeNode root){  
   if (root!=null){  
      System.out.print(root.value);  
      dfs(root.left);  
      dfs(root.right);  
   }         
}

​ 我们发现这和前序遍历一模一样,确实,因为前序遍历和后序遍历都属于树的深度优先遍历。都是先顺着一条路走到底,然后再返回上一级再继续走。

四、合并二叉树

1、题目描述

(1)描述

​ 已知两棵二叉树,将它们合并成一棵二叉树。合并规则是:都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。

(2)示例

在这里插入图片描述

2、思路分析

​ 这里是将两个二叉树进行合并,这里的合并不是节点的合并,而是值的合并,都有则合并,一方有则用一方。合并的思路是使用前序遍历进行合并,具体的递归三要素为:

  • 终止条件:当遍历到叶子节点,进行返回值返回
  • 返回值:三种返回情况,一是返回新的合并节点,二是当二叉树t1对应节点为null使返回t2节点,三是当t2对应节点为null时返回t1节点【返回的值是节点】
  • 本级任务:一是合并两个节点的值为新的节点,二是赋值节点的左节点和右节点为下一级递归返回

3、Java实现

public class Solution {
    public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
        //返回值
        if(t1==null) return t2;
        if(t2==null) return t1;
        //本级任务
        TreeNode cur = new TreeNode(t1.val+t2.val);
        cur.left = mergeTrees(t1.left,t2.left);
        cur.right = mergeTrees(t1.right,t2.right);
        //返回值
        return cur;
    }
}

五、总结

(1)树的遍历

​ 树的遍历有:前(中/后)序遍历、广度优先遍历(层序遍历)、深度优先遍历【前序遍历或后序遍历】。

(2)递归

​ 之前我们主要强调要记得给递归设定终止条件并返回,这次总结了编写递归函数的三要素:

  • 终止条件:执行到最后停止的条件
  • 返回值:每层递归返回时向上返回的值
  • 本级任务:每层递归一般要做两件事,一个是进入下一层递归,另一个是做一点坏事

​ 如果有返回值,则说明是使用了分治的思想,即使用递归将问题逐步拆分,在返回时进行结果的合并。如果没有返回值只是为了干坏事,那只需要考虑终止条件和本级任务即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未来村村长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值