二叉树相关

一、概念

二、题目

2.1 把数组转换成二叉树

2.2.1 使用队列方式

public static Node getTreeFromArr2(int[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }

        LinkedList<Node> quque = new LinkedList<>();
        Node root = new Node(arr[0]);

        quque.add(root);
        int index = 1;
        while(!quque.isEmpty()){
            // pop 0的时候,刚好操作1、2
            // pop 1的时候,刚好操作3、4
            // pop 2的时候,刚好操作5、6
            Node temp = quque.pop();
            if(index < arr.length){
                temp.left = new Node(arr[index]);
                quque.add(temp.left);
                index++;
            }

            if(index < arr.length){
                temp.right = new Node(arr[index]);
                quque.add(temp.right);
                index++;
            }
        }
        return root;
    }

2.2.3 使用堆的方式

private static Node getTreeFromArr(int[] arr) {
        Map<Integer, Node> map = new HashMap();
        for (int i = arr.length - 1; i >= 0; i--) {
            Node temp = new Node(arr[i]);
            temp.value = arr[i];
            map.put(i, temp);
            int leftChildIndex = 2 * i + 1;
            int rightChildIndex = 2 * i + 2;
            if (leftChildIndex < arr.length) {
                temp.left = map.get(leftChildIndex);
            }
            if (rightChildIndex < arr.length) {
                temp.right = map.get(rightChildIndex);
            }
        }
        return map.get(0);
    }

2.2 二叉树进行前序、中序、后序遍历

2.2.1 递归的方式

@ToString
    public static class Node {
        public Node left;
        public Node right;
        public int value;

        public Node(int value) {
            this.value = value;

        }
    }

    public static void main(String[] args) {
        int[] arr = {0, 1, 2, 3, 4, 5, 6};
//        Node head = getTreeFromArr(arr);
        Node head2 = getTreeFromArr2(arr);
//        System.out.println(JSON.toJSONString(head));
        System.out.println(JSON.toJSONString(head2));

        /*
            前序遍历:[0, 1, 3, 4, 2, 5, 6]
            中序遍历:[3, 1, 4, 0, 5, 2, 6]
            后序遍历:[3, 4, 1, 5, 6, 2, 0]
         */
        preorderPrint(head2);
        System.out.println();
        inorderPrint(head2);
        System.out.println();
        postorderPrint(head2);
    }

    /**
     * 前序遍历(中左右)
     */
    public static void preorderPrint(Node temp){
        if(null == temp){
            return;
        }
        System.out.print(temp.value + ",");
        preorderPrint(temp.left);
        preorderPrint(temp.right);
    }

    /**
     * 中序遍历(左中右)
     */
    public static void inorderPrint(Node temp){
        if(null == temp){
            return;
        }
        inorderPrint(temp.left);
        System.out.print(temp.value + ",");
        inorderPrint(temp.right);
    }
    /**
     * 右序遍历(左中右)
     */
    public static void postorderPrint(Node temp){
        if(null == temp){
            return;
        }
        postorderPrint(temp.left);
        postorderPrint(temp.right);
        System.out.print(temp.value + ",");
    }


    public static Node getTreeFromArr2(int[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }

        LinkedList<Node> quque = new LinkedList<>();
        Node root = new Node(arr[0]);

        quque.add(root);
        int index = 1;
        while(!quque.isEmpty()){
            // pop 0的时候,刚好操作1、2
            // pop 1的时候,刚好操作3、4
            // pop 2的时候,刚好操作5、6
            Node temp = quque.pop();
            if(index < arr.length){
                temp.left = new Node(arr[index]);
                quque.add(temp.left);
                index++;
            }

            if(index < arr.length){
                temp.right = new Node(arr[index]);
                quque.add(temp.right);
                index++;
            }
        }
        return root;
    }

2.2.2 栈的方式

1、前序遍历(宽度遍历)

/**
     * Stack方法
     * 前序遍历(中左右)
     */
    public static void preorderPrintByStack(Node root) {
        Stack<Node> stack = new Stack<>();
        stack.push(root);

        // 可以不用queue,可以直接打印,省空间 N
        // 我加一个 queue的目的是为了后序的翻转好理解
        Queue<Node> queue = new LinkedList<>();

        while (!stack.isEmpty()) {
            Node temp = stack.pop();
//            System.out.print(temp.value + ",");
            // 此处可以不打印,直接入一个新的 queue
            queue.offer(temp);
            if (temp.right != null) {
                stack.push(temp.right);
            }
            if (temp.left != null) {
                stack.push(temp.left);
            }
        }
        System.out.print("preorderPrintByStack -> ");
        while (!queue.isEmpty()) {
            System.out.print(queue.poll().value + ",");
        }
        System.out.println();
    }
/**
     * 宽度遍历,其实就是中左右,也就是前序遍历
     * 用一个 queue 辅助也是可以搞定的
     * @param head
     */
    public static void widthPrint(Node head){
        if(null == head){
            return;
        }
        Queue<Node> queue = new LinkedList<>();
        queue.offer(head);

        while(!queue.isEmpty()){
            Node temp = queue.poll();
            System.out.print(temp.value + ",");
            if(temp.left != null){
                queue.offer(temp.left);
            }
            if(temp.right != null){
                queue.offer(temp.right);
            }
        }
    }
2、中序遍历


    /**
     * Stack方法
     * 中序遍历(左中右)
     */
    public static void inOrderPrintByStack(Node root) {
        if(null == root){
            return;
        }
        Node current = root;
        Stack<Node> stack = new Stack<>();

        // 可以不用queue,可以直接打印,省空间 N
        // 我加一个 queue的目的是为了后序的翻转好理解
        Queue<Node> queue = new LinkedList<>();

        while (current != null || !stack.isEmpty()) {
            // 如果current不是null,那么就一直往左找下去
            while(current != null){
                stack.push(current);
                current = current.left;
            }
            current = stack.pop();
//            System.out.print(current.value + ",");
            queue.offer(current);
            // 左边已经干完了,那么就一直往右找
            current = current.right;
        }

        System.out.print("inOrderPrintByStack -> ");
        while (!queue.isEmpty()) {
            System.out.print(queue.poll().value + ",");
        }
    }
3、右序遍历

/**
     * 右序遍历(左右中)
     * 翻过来就是 中右左, 因为前序是中左右,前序是先压right再压left,那么反过来,先压left再压right的话,就会是中右左了
     */
    public static void postorderPrintByStack(Node temp) {
        if (null == temp) {
            return;
        }
        Stack<Node> stackA = new Stack<>();
        stackA.push(temp);

        // 注意和之前的区别,上面的中序和前序都是 queue ,FIFO,那么 Stack 的FILO,就能实现这个翻转
        Stack<Node> stackB = new Stack<>();

        while(!stackA.isEmpty()){
            temp = stackA.pop();
            stackB.push(temp);
            if(temp.left != null){
                stackA.push(temp.left);
            }
            if(temp.right != null){
                stackA.push(temp.right);
            }
        }

        System.out.print("postorderPrintByStack -> ");
        while (!stackB.isEmpty()) {
            System.out.print(stackB.pop().value + ",");
        }
    }
0、测试代码汇总
@ToString
    public static class Node {
        public Node left;
        public Node right;
        public int value;

        public Node(int value) {
            this.value = value;

        }
    }

    public static void main(String[] args) {
        int[] arr = {0, 1, 2, 3, 4, 5, 6};
//        Node head = getTreeFromArr(arr);
        Node head2 = getTreeFromArr2(arr);
//        System.out.println(JSON.toJSONString(head));
        System.out.println(JSON.toJSONString(head2));

        /*
            前序遍历:[0, 1, 3, 4, 2, 5, 6]
            中序遍历:[3, 1, 4, 0, 5, 2, 6]
            后序遍历:[3, 4, 1, 5, 6, 2, 0]
         */

        System.out.println("preorderPrint ->");
        preorderPrint(head2);
        System.out.println();

        System.out.println("inorderPrint ->");
        inorderPrint(head2);
        System.out.println();

        System.out.println("postorderPrint ->");
        postorderPrint(head2);
        System.out.println();
        System.out.println("——————————");


        preorderPrintByStack(head2);
        inOrderPrintByStack(head2);
        postorderPrintByStack(head2);
    }

    /**
     * 前序遍历(中左右)
     */
    public static void preorderPrint(Node temp) {
        if (null == temp) {
            return;
        }
        System.out.print(temp.value + ",");
        preorderPrint(temp.left);
        preorderPrint(temp.right);
    }

    /**
     * 中序遍历(左中右)
     */
    public static void inorderPrint(Node temp) {
        if (null == temp) {
            return;
        }
        inorderPrint(temp.left);
        System.out.print(temp.value + ",");
        inorderPrint(temp.right);
    }

    /**
     * 右序遍历(左中右)
     */
    public static void postorderPrint(Node temp) {
        if (null == temp) {
            return;
        }
        postorderPrint(temp.left);
        postorderPrint(temp.right);
        System.out.print(temp.value + ",");
    }

    /**
     * Stack方法
     * 前序遍历(中左右)
     */
    public static void preorderPrintByStack(Node root) {
        Stack<Node> stack = new Stack<>();
        stack.push(root);

        // 可以不用queue,可以直接打印,省空间 N
        // 我加一个 queue的目的是为了后序的翻转好理解
        Queue<Node> queue = new LinkedList<>();

        while (!stack.isEmpty()) {
            Node temp = stack.pop();
//            System.out.print(temp.value + ",");
            // 此处可以不打印,直接入一个新的 queue
            queue.offer(temp);
            if (temp.right != null) {
                stack.push(temp.right);
            }
            if (temp.left != null) {
                stack.push(temp.left);
            }
        }
        System.out.print("preorderPrintByStack -> ");
        while (!queue.isEmpty()) {
            System.out.print(queue.poll().value + ",");
        }
        System.out.println();
    }

    /**
     * Stack方法
     * 中序遍历(左中右)
     */
    public static void inOrderPrintByStack(Node root) {
        if(null == root){
            return;
        }
        Node current = root;
        Stack<Node> stack = new Stack<>();

        // 可以不用queue,可以直接打印,省空间 N
        // 我加一个 queue的目的是为了后序的翻转好理解
        Queue<Node> queue = new LinkedList<>();

        while (current != null || !stack.isEmpty()) {
            // 如果current不是null,那么就一直往左找下去
            while(current != null){
                stack.push(current);
                current = current.left;
            }
            current = stack.pop();
//            System.out.print(current.value + ",");
            queue.offer(current);
            // 左边已经干完了,那么就一直往右找
            current = current.right;
        }

        System.out.print("inOrderPrintByStack -> ");
        while (!queue.isEmpty()) {
            System.out.print(queue.poll().value + ",");
        }
    }


    /**
     * 右序遍历(左右中)
     * 翻过来就是 中右左, 因为前序是中左右,前序是先压right再压left,那么反过来,先压left再压right的话,就会是中右左了
     */
    public static void postorderPrintByStack(Node temp) {
        if (null == temp) {
            return;
        }
        Stack<Node> stackA = new Stack<>();
        stackA.push(temp);

        // 注意和之前的区别,上面的中序和前序都是 queue ,FIFO,那么 Stack 的FILO,就能实现这个翻转
        Stack<Node> stackB = new Stack<>();

        while(!stackA.isEmpty()){
            temp = stackA.pop();
            stackB.push(temp);
            if(temp.left != null){
                stackA.push(temp.left);
            }
            if(temp.right != null){
                stackA.push(temp.right);
            }
        }

        System.out.print("postorderPrintByStack -> ");
        while (!stackB.isEmpty()) {
            System.out.print(stackB.pop().value + ",");
        }
    }




    public static Node getTreeFromArr2(int[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }

        LinkedList<Node> quque = new LinkedList<>();
        Node root = new Node(arr[0]);

        quque.add(root);
        int index = 1;
        while (!quque.isEmpty()) {
            // pop 0的时候,刚好操作1、2
            // pop 1的时候,刚好操作3、4
            // pop 2的时候,刚好操作5、6
            Node temp = quque.pop();
            if (index < arr.length) {
                temp.left = new Node(arr[index]);
                quque.add(temp.left);
                index++;
            }

            if (index < arr.length) {
                temp.right = new Node(arr[index]);
                quque.add(temp.right);
                index++;
            }
        }
        return root;
    }

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

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

相关文章

有大量虾皮买家号想防关联该怎么做?

Shopee平台规定一个买家只能拥有一个买家号&#xff0c;如果一台电脑或者一个手机同时登录好几个买家号&#xff0c;那么很有可能就会关联封号的。那么有大量虾皮买家号想防关联该怎么做&#xff1f; 如果想要运用大量的shopee买家号来操作&#xff0c;那么需要使用有防指纹技术…

利用vscode连接远程服务器进行代码调试

文章目录 一、vscode下载二、连接服务器1. 安装remote development套件2. 配置ssh3. 连接服务器4. 打开服务器文件路径 三、支持GUI显示1. windows系统安装xserver服务&#xff1a;可以用xming或VcXsrv2. windows系统(安装了vscode的系统)下安装插件3. vscode实现免密登录远程服…

<蓝桥杯软件赛>零基础备赛20周--第6周--数组和队列

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…

Ansys Speos | 如何利用Speos联合optiSLang进行光导优化设计

在本例中&#xff0c;我们将使用 Speos 和 optiSLang 实现光导的设计优化&#xff0c;以实现汽车日行灯、内饰氛围灯等的光导设计&#xff0c;并改善光导亮度的均匀性&#xff0c;以自动优化设计的方式实现更好的照明外观。 概述 在汽车照明应用中&#xff0c;日行灯是一个独特…

[文件读取]Grafana未授权任意文件读取

1.1漏洞描述 漏洞编号Grafana未授权任意文件读取漏洞类型文件读取漏洞等级⭐⭐⭐漏洞环境VULFOCUS攻击方式 描述: Grafana是一个跨平台、开源的数据可视化网络应用程序平台。用户配置连接的数据源之后&#xff0c;Grafana可以在网络浏览器里显示数据图表和警告。 Grafana 存在…

【自定义列表头】vue el-table表格自定义列显示隐藏,多级表头自定义列显示隐藏,自由搭配版本和固定列版本【注释详细】

前言 功能介绍 最近遇到一个功能&#xff0c;需要的是把表格的列可以配置&#xff0c; 用户可以根据自己想要看的数据来改变表头列显示哪些隐藏哪些。 于是我做了两个版本。第一个版本是自由搭配的。 就是提前顶号所有的列&#xff0c;然后自己可以拖拽到想要位置顺序。 也可以…

打开IE浏览器

原文地址&#xff1a;https://www.xiaoheiwoo.com/windows-11-internet-explorer/#:~:text%E5%A6%82%E4%BD%95%E5%9C%A8%20Windows11%20%E4%B8%AD%E5%90%AF%E7%94%A8%20IE%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%843%E7%A7%8D%E6%96%B9%E6%B3%95%201%20%E6%96%B9%E6%B3%95%E4%B8%80…

俄罗斯方块

一.准备工作 先创建一个新的Java项目命名为“俄罗斯方块”。再在该项目中创建一个文件夹命名为”images”&#xff0c;并将所需的图片素材拖入该文件夹。 二.代码呈现 编写小方块类&#xff1a; import java.awt.image.BufferedImage;/*** 描述:小方块类* 属性&#xff1a;…

Nas搭建webdav服务器并同步Zotero科研文献

无需云盘&#xff0c;不限流量实现Zotero跨平台同步&#xff1a;内网穿透私有WebDAV服务器 文章目录 无需云盘&#xff0c;不限流量实现Zotero跨平台同步&#xff1a;内网穿透私有WebDAV服务器一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zote…

不会代码的时候,如何使用Jmeter完成接口测试?

1.接口测试简介 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 2.接口测试流程 接口测试…

推荐一个非常好用的uniapp的组件库【TMUI3.0】

文章目录 前言官网地址如何使用&#xff1f;注意事项后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端系列文章 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果…

Java虚拟机运行时数据区结构详解

Java虚拟机运行时数据区结构如图所示 程序计数器 程序计数器&#xff08;Program Counter Register&#xff09;是一块较小的内存空间&#xff0c;它可以看作是当前线程所执行的字节码的行号指示器。 多线程切换时&#xff0c;为了能恢复到正确的执行位置&#xff0c;每条线程…

[Python学习笔记]Python 性能分析

在上一章节 [Python学习笔记]Requests性能优化之Session 中&#xff0c;通过在 Resquests 中使用 session&#xff0c;将 Python 脚本的运行效率提升了 3 倍。但当时对问题的排查主要是基于程序实现逻辑的推断&#xff0c;并没有实质性的证据。 本次使用 Python 的性能分析工具…

【每日一题】最长奇偶子数组

文章目录 Tag题目来源解题思路方法一&#xff1a;枚举方法二&#xff1a;一次遍历 其他语言python3 写在最后 Tag 【一次遍历】【枚举】【数组】【2023-11-16】 题目来源 2760. 最长奇偶子数组 解题思路 方法一&#xff1a;枚举 本题有多种方法可以解决&#xff0c;最朴素的…

如何有效防止公司内部的信息泄露?

信息泄露对公司可能带来严重影响&#xff0c;因此采取一系列措施以确保信息安全至关重要。以下是一些建议&#xff1a; 部署综合的防泄密软件&#xff1a; 在公司内部&#xff0c;使用专业的防泄密软件如华企盾DSC系统&#xff0c;涵盖文件加密、U盘管控、桌面行为管理、日志审…

极智AI | Realtime Multi-Person人体姿态估计之OpenPose

欢迎关注我的公众号 [极智视界],获取我的更多经验分享 大家好,我是极智视界,本文来介绍一下 Realtime Multi-Person人体姿态估计之OpenPose。 邀您加入我的知识星球「极智视界」,星球内有超多好玩的项目实战源码下载,链接:https://t.zsxq.com/0aiNxERDq OpenPose 主要是…

qt使用AES加密、解密字符串

一、AES算法 AES (Advanced Encryption Standard) 是一种对称加密算法&#xff0c;是目前被广泛使用的数据加密标准之一。该算法旨在取代DES (Data Encryption Standard) 算法。AES最初由比利时密码学家 Joan Daemen 和 Vincent Rijmen 提出&#xff0c;经过多年的演化、改进和…

TSINGSEE青犀智慧机房AI+视频智能监管方案,保障机房设备稳定运转

一、背景与需求分析 随着互联网的高速发展&#xff0c;机房数量及配套环境设备日益增多&#xff0c;其运行状况直接决定着企业组织的运营效率和服务质量。作为企业信息化的核心&#xff0c;机房的安全监测与管理&#xff0c;不仅关系到企业的稳定运转&#xff0c;同时也关系到…

jffs2文件系统(二)

本篇文章讲解一下如何制作jffs2文件系统&#xff0c;以及如何在linux下把jffs2作为根文件系统使用。 文件系统制作 制作工具&#xff1a;mtd_utils&#xff0c;可以自己安装 mkfs.jffs2 -o root-uclibc-jffs2 -r root-uclibc -e 0x10000 -s 0x1000 -n -l -X zlib --pad0x10000…

(珍藏版)Redis经典面试题32道,吊打面试官!

文章目录 Redis最新2023年面试题高级面试题及附答案解析(3)01、请用 Redis 和任意语言实现一段恶意登录保护的代码&#xff1f;02、Pipeline 有什么好处&#xff0c;为什么要用 pipeline&#xff1f;03、Redis 常用管理命令有哪些&#xff1f;04、Redis 持久化数据和缓存怎么做…