二叉树---java---黑马

二叉树

遍历

遍历分两种

广度优先遍历

尽可能先访问距离根节点最近的节点,也称之为层序遍历。
在这里插入图片描述

深度优先遍历

对于二叉树,进一步分为三种

  1. pre-order前序遍历,对于每一颗子树,先访问该节点,然后是左子树,最后是右子树;
  2. in-order中序遍历,对于每一颗子树,先访问左子树,然后是该节点,最后是右子树;
  3. post-order后序遍历,对于每一颗子树,先访问左子树,然后是右子树,最后是该节点;
使用递归方式实现
前序遍历
public class TreeNode{
    TreeNode left;
    int value;
    TreeNode right;
    
    public TreeNode() {
        
    }
    
    public TreeNode(TreeNode left, int value, TreeNode) {
        this.left = left;
        this.value = value;
        this.right = right;
    }
    
    @Override
    public String toString() {
        return 	String.valueOf(this.value);
    }
}
public class TreeTraversal{
    
    public static void main(String[] args) {
        TreeNode root = new TreeNode(
            new TreeNode(new TreeNode(4, 2, null)), 
            1, 
            new TreeNode(new TreeNode(5, 3, new TreeNode(6))));
    }
    
    public void preOrder(TreeNode node) {
        if (node == null) {
            return;
        }
        System.out.println(node.value + "\t");	// 值
        preOrder(node.left);					// 左
        preOrder(node.right);					// 右
    }
    
    public void inOrder(TreeNode node) {
        if (node == null) {
            return;
        }
        preOrder(node.left);					// 左
        System.out.println(node.value + "\t");	// 值
        preOrder(node.right);					// 右
    }
    
    public void postOrder(TreeNode node) {
        if (node == null) {
            return;
        }
        preOrder(node.left);					// 左
        preOrder(node.right);					// 右
        System.out.println(node.value + "\t");	// 值
    }
    
}
非递归实现
前序遍历和中序遍历
public class TreeTraversal{
    
    public static void main(String[] args) {
        TreeNode root = new TreeNode(
            new TreeNode(new TreeNode(4, 2, null)), 
            1, 
            new TreeNode(new TreeNode(5, 3, new TreeNode(6))));
        Stack<Integer> stack = new Stack<>();
        TreeNode curr = root;
        while (curr != null || !stack.isEmpty()) {
            if (curr != null) {
                System.out.println(curr.value);		// 前序遍历
                stack.push(curr);
                curr = curr.left;
            } else {
                TreeNode pop = stack.pop();
                System.out.println(pop.value);		// 中序遍历
                curr = pop.right;
            }
        }
    }
}
后序遍历
public class TreeTraversal{
    
    public static void main(String[] args) {
        TreeNode root = new TreeNode(
            new TreeNode(new TreeNode(4, 2, null)), 
            1, 
            new TreeNode(new TreeNode(5, 3, new TreeNode(6))));
        Stack<Integer> stack = new Stack<>();
        TreeNode curr = root;
        TreeNode pop = null;
        while (curr != null || !stack.isEmpty()) {
            if (curr != null) {
                stack.push(curr);
                curr = curr.left;
            } else {
                TreeNode peek = stack.peek();
                if (peek.right == null || peek.right == peek) {
                    pop = stack.pop();
                    System.out.println(pop.value);		// 后序遍历
                } else {
                    curr = peek.right;
                }
            }
        }
    }
}
同时实现前序遍历、中序遍历和后序遍历
public class TreeTraversal{
    
    public static void main(String[] args) {
        TreeNode root = new TreeNode(
            new TreeNode(new TreeNode(4, 2, null)), 
            1, 
            new TreeNode(new TreeNode(5, 3, new TreeNode(6))));
        Stack<Integer> stack = new Stack<>();
        TreeNode curr = root;		// 当前节点
        TreeNode pop = null;		// 最近一次弹栈节点
        while (curr != null || !stack.isEmpty()) {
            if (curr != null) {
                stack.push(curr);
                // 待处理左子树
                System.out.println(curr.value);			// 前序遍历
                curr = curr.left;
            } else {
                TreeNode peek = stack.peek();
                // 无右子树
                if (peek.right == null) {
                    System.out.println(peek.value);		// 中序遍历
                    pop = stack.pop();
                    System.out.println(pop.value);		// 后序遍历
                } 
                // 右子树处理完成
                else if (peek.right == peek) {
                    pop = stack.pop();
                    System.out.println(pop.value);		// 后序遍历
                } 
                // 待处理右子树
                else {
                    System.out.println(peek.value);		// 中序遍历
                    curr = peek.right;
                }
            }
        }
    }
}

Leetcode

Leetcode101对称二叉树

public class Leetcode101{
    
    public boolean isSymmetric(TreeNode root) {
        return check(root.left, root.right);
    }
    
    public boolean check(TreeNode left, TreeNode right) {
        if (left == null && right == null) {
            return true;
        }
        if (right == null || left == null) {
            return false;
        }
        if (left.value != right.value) {
            return false;
        }
        return check(left.left, right.right) && check(left.right, right.left);
    }
}

Leetcode104最大深度

方法一

使用递归

public class Leetcode104{
    
   	public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        int i = maxDepth(root.left);
        int j = maxDepth(root.right);
        return Math.max(i, j) + 1;
    }
}
方法二

使用后序遍历

public class Leetcode104{
    
   	public int maxDepth(TreeNode root) {
        TreeNode curr = root;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode pop = null;		// 最近一次弹栈元素/节点
        int max = 0;				// 栈的最大深度
        while(curr != null || !stack.isEmpty()) {
            if (curr != null) {
                stack.push(curr);
                if (stack.size() > max) {
                    max = stack.size();
                }
                curr = curr.next;
            } else {
                TreeNode peek = stack.peek();
                if (peek.right == null || peek.right == pop) {
                    pop = stack.pop();
                } else {
                    curr = peek.right;
                }
            }
        }
    }
}
方法三

使用层序遍历

public class Leetcode104{
    
   	public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        int depth = 0;
        while(!queue.isEmpty()) {
            int size = queue.size();		// 写在循环内,需要多次调用,所以写在循环外
            for(int i = 0; i < size; i++) {
                TreeNode poll = queue.poll();
                if (poll.left != null) {
                    queue.offer(poll.left);
                }
                if (poll.right != null) {
                    queue.offer(poll.right);
                }
            }
            depth++;
        }
        return depth;
    }
}

Leetcode111二叉树最小深度

方法一
public class Leetcode111{
    
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int d1 = minDepth(root.left);
        int d2 = minDepth(root.right);
        if (d1 == 0) {	// 当左子树为空
            return d2 + 1;
        } 
        if (d2 == 0) {	// 当右子树为空
            return d1 + 1;
        }
        return Math.min(d1, d2) + 1;
    }
}
方法二

使用层序遍历实现,找到第一个叶子节点,求得最小深度

public class Leetcode111{
    
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        LinkedList<TreeNode> queue = new LinkedList<>();	// LinkedList可以作为双向链表、队列、栈
        queue.offer(root);
        int c1 = 1;
        int depth = 0;
        while (!queue.isEmpty()) {
            int c2 = 0;
            depth++;
            for(int i = 0; i < c1; i++) {
                TreeNode poll = queue.poll();
                if (poll.left == null && poll.right == null) {
                    return depth;
                }
                if (poll.left != null) {
                    queue.offer(poll.left);
                    c2++;
                }
                if (poll.right != null) {
                    queue.offer(poll.right);
                    c2++;
                }
            }
            c1 = c2;
        }
        return depth;
    }
}

Leetcode226

二叉树反转

public class Leetcode226{
    public TreeNode invertTree(TreeNode root) {
        if (root == null ||(root.left == null && root.right == null)) {
            return root;
        }
        fn(root);
        return root;
    }
    
    public void fn(TreeNode node) {
        if (node == null) {
            return;
        }
        TreeNode temp = node.left;
        node.left = node.right;
        node.right = temp;
        fn(node.left);
        fn(node.right);
    }
}

后缀表达式构建二叉树

中缀表达式				(2 - 1) * 3
后缀表达式/逆波兰表达式	21-3*
    
    表达树
    *
   / \
  -   3
 / \
2   1 
public class ExpressionTree{
    
    public TreeNode constructExpressionTree (String[] tokens){
        Stack<TreeNode> stack = new Stack<>();
        for(String t : tokens) {
            switch (t) {
                case "+", "-", "*", "/" -> {	// 运算符
                    TreeNode right = stack.pop();
                    TreeNode left = stack.pop();
                    TreeNode parent = new TreeNode(t);
                    parent.left = left;
                    parent.right = right;
                    stack.push(parent);
                }
                default -> {					// 数字
                    stack.push(new TreeNode(t));
                }    
            }
        }
        return stack.peek();
    }
}

Leetcode105

根据前序遍历和中序遍历,得到二叉树

public class Leetcode105{
    public TreeNode buildTree(int[] preOrder, int inOrder) {
        if (preOrder.length == 0) {
            return null;
        }
        // 创建根节点
        int rootValue = preOrder[0];
        TreeNode root = new TreeNode(rootValue);
        for(int i = 0; i < inOrder.length; i++) {
            if (inOrder[i] == rootValue) {
                int[] inLeft = Arrays.copyOfRange(inOrder, 0, i);
                int[] inRight = Arrays.copyOfRange(inOrder, i + 1, inOrder.length);
                
                int[] preLeft = preLeftArrays.copyOfRange(preOrder, 1, i + 1);
                int[] preRight = Arrays.copyOfRange(preOrder, i + 1, preOrder.length);
                
                root.left = buildTree(preLeft, inLeft);
                root.right = buildTree(preRight, inRight);
                break;
            }
        }
        return root;
    }
}

Leetcode106

根据中序遍历和后序遍历得到二叉树

public class Leetcode106{
    public TreeNode buildTree(int[] inOrder, int postOrder) {
        if (postOrder.length == 0) {
            return null;
        }
        // 创建根节点
        int rootValue = postOrder[postOrder.length - 1];
        TreeNode root = new TreeNode(rootValue);
        for(int i = 0; i < inOrder.length; i++) {
            if (inOrder[i] == rootValue) {
                int[] inLeft = Arrays.copyOfRange(inOrder, 0, i);
                int[] inRight = Arrays.copyOfRange(inOrder, i + 1, inOrder.length);
                
                int[] postLeft = preLeftArrays.copyOfRange(preOrder, 0, i);
                int[] postRight = Arrays.copyOfRange(preOrder, i, preOrder.length - 1);
                
                root.left = buildTree(inLef, tpostLeft);
                root.right = buildTree(inRight, postRight);
                break;
            }
        }
        return root;
    }
}
            int[] inRight = Arrays.copyOfRange(inOrder, i + 1, inOrder.length);
            
            int[] postLeft = preLeftArrays.copyOfRange(preOrder, 0, i);
            int[] postRight = Arrays.copyOfRange(preOrder, i, preOrder.length - 1);
            
            root.left = buildTree(inLef, tpostLeft);
            root.right = buildTree(inRight, postRight);
            break;
        }
    }
    return root;
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/882357.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索RESTful风格的网络请求:构建高效、可维护的API接口【后端 20】

探索RESTful风格的网络请求&#xff1a;构建高效、可维护的API接口 在当今的软件开发领域&#xff0c;RESTful&#xff08;Representational State Transfer&#xff09;风格的网络请求已经成为构建Web服务和API接口的标配。RESTful风格以其简洁、无状态、可缓存以及分层系统等…

利用影刀实现批量发布文章的RPA流程(附视频演示)

前言 大家好&#xff0c;我是小智。在这篇文章中&#xff0c;我将分享一个实战案例&#xff0c;展示如何利用影刀实现批量发布文章的RPA流程。这里主要介绍其中一个简单步骤&#xff0c;其它步骤将通过视频演示。有使用方面的疑问可以留言。 影刀是一款强大的自动化工具&#x…

Java项目实战II基于Java+Spring Boot+MySQL的网上租贸系统设计与实现(开发文档+源码+数据库)

目录 一、前言 二、技术介绍 三、系统实现 四、论文参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 "随着…

简单的云存储靶场

搭建靶场 我这里使用tx云&#xff0c;请自行搭建 https://shuihui2211-1329809954.cos.ap-nanjing.myqcloud.com 复现 私有读写 访问权限为私有读写时&#xff0c;我们访问url则会出现如下提示 目录遍历 漏洞成因 将policy权限设置为所有操作时 复现 我这里上传了一…

java-----异常

目录 异常&#xff1a;代表程序出现的问题 运行时异常和编译时异常的区别&#xff1f; 异常的作用&#xff1a; 异常的处理方式: 异常中常见的方法: 抛出异常: 自定义异常: 异常&#xff1a;代表程序出现的问题 Exception:叫做异常&#xff0c;代表程序可能出现的问题。…

Python 连接mysql数据库,并且执行查询

之前一直在写Java&#xff0c;但是随着python的崛起&#xff0c;自己也被慢慢的带入到了这样的一个阵营&#xff0c;学习python&#xff0c;了解机器学习 曾经有一个.... 不谈曾经&#xff0c;现在的我是一个小菜鸟&#xff0c;用学习Java实现业务的需求来学习python 项目的目…

科研绘图系列:R语言树结构聚类热图(cluster heatmap)

文章目录 介绍加载R包导入数据数据预处理画图修改图形导出数据系统信息介绍 热图结合树结构展示聚类结果通常用于展示数据集中的模式和关系,这种图形被称为聚类热图或层次聚类热图。在这种图中,热图部分显示了数据矩阵的颜色编码值,而树结构(通常称为树状图或聚类树)则显…

iptables限制网速

1、使用hashlimit来限速 #从eth0网卡进入INPUT链数据&#xff0c;使用模块hashlimit 限制网速为100kb/s或2mb/s,超过限制的数据包会被DROP。OUTPUT链同理&#xff0c;mode为srcip&#xff0c;有4个mode选项: srcip&#xff08;默认匹配每个源地址IP&#xff0c;配置指定源地址…

计算机网络33——文件系统

1、chmod 2、chown 需要有root权限 3、link 链接 4、unlink 创建临时文件&#xff0c;用于非正常退出 5、vi vi可以打开文件夹 ../是向外一个文件夹 6、ls ls 可以加很多路径&#xff0c;路径可以是文件夹&#xff0c;也可以是文件 ---------------------------------…

Tcping:一款实用的端口存活检测工具

简介 tcping 是一个基于TCP协议的网络诊断工具,通过发送 TCP SYN/ACK包来检测目标主机的端口状态。 官网:tcping.exe - ping over a tcp connection 优点: (1)监听服务器端口状态:tcping 可以检测指定端口的状态,默认是80端口,也可以指定其他端口。 (2)显示ping返…

桌面便签哪个好用?好用的便签软件推荐?

随着信息技术的发展&#xff0c;我们的生活方式也发生了翻天覆地的变化。从纸质笔记本到电子便签&#xff0c;这不仅仅是载体的转换&#xff0c;更是思维习惯的一次革新。在这个数字时代&#xff0c;如何利用科技工具来辅助我们更好地管理时间和信息&#xff0c;成为了值得探讨…

Java刷题知识总结(一)

1.局部变量参与运算前是必须要初始化的&#xff0c;比如下面的代码就会编译出错&#xff0c;提示y必须要初始化。 public static void main(String[] args) {int x 1;int y;int z x y; } 2.ArrayList和Vector主要区别是什么&#xff1f; A Vector与ArrayList一样&#xf…

计算机毕业设计 扶贫助农系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

记一次Apache点击startup立马闪退的修复

人们总是在靠近幸福时患得患失 --生菜特斯拉 这两天频繁在各个虚拟机中使用apache搭建服务&#xff0c;但是时而会出现点击startup.bat启动脚本后立马出现闪退&#xff0c;所以记录一下。 一、环境复现 实验器材 1、win10虚拟机 2、apache项目 3、JDK&#xff08;1.8&am…

Linux高级I/O:多路转接模型

目录 一.常见的IO模型介绍二.多路转接I/O1.select1.1.函数解析1.2. select特点和缺点1.3.基于 select 的多客户端网络服务器 2.poll2.1.poll函数解析2.2.poll特点和缺点2.3.基于poll的tcp服务器 3.epoll3.1.系列函数解析3.2.epoll原理解析2.3.基于 select 的多客户端网络服务器…

Java 入门指南:JVM(Java虚拟机)—— Java 类加载器详解

类加载器 类加载器&#xff08;Class Loader&#xff09;是 Java 虚拟机&#xff08;JVM&#xff09;的一部分&#xff0c;它的作用是将类的字节码文件&#xff08;.class 文件&#xff09;从磁盘或其他来源加载到 JVM 中。类加载器负责查找和加载类的字节码文件&#xff0c;并…

BEV学习--Nuscenes数据集解读

一、Nuscenes数据集简介 Nuscenes数据的采集来自不同城市的1000个场景中&#xff0c;采集车上配备了完善的传感器&#xff0c;包括6个相机&#xff08;CAM&#xff09;、1个激光雷达&#xff08;LIDAR&#xff09;、5个毫米波雷达&#xff08;RADAR&#xff09;、IMU和GPS&…

论文(六):Fire-Net: A Deep Learning Framework for Active Forest Fire Detection

文章目录 1.Introduction2.Study Area2.1Landsat-8 Dataset2.2Inventory data 3.Methodology3.1Image Pre-processing3.2Proposed Deep Learning Architecture (Fire-Net)3.2.1Convolution Layers3.2.2 Evaluation Indices/methods or accuracy assessment. 4.Results4.1 Austr…

新一代图像生成E2E FT:深度图微调突破

文章地址&#xff1a;Fine-Tuning Image-Conditional Diffusion Models is Easier than You Think 项目主页&#xff1a;https://gonzalomartingarcia.github.io/diffusion-e2e-ft/ 代码地址&#xff1a;https://github.com/VisualComputingInstitute/diffusion-e2e-ft 机构&am…

SpringBoot 整合 apache fileupload 轻松实现文件上传与下载(通用版)

我们以Thymeleaf页面模板引擎为例&#xff0c;简单介绍利用 apache fileupload 工具实现文件上传的功能。 2.1、添加相关依赖包 首先创建一个基础的 Spring Boot 项目&#xff0c;并引入相关的依赖包。 2.2、添加相关配置参数 2.3、文件上传示例 对应文件上传的Controller类&…