日撸 Java 三百行day21-22

news2024/10/6 7:52:42

文章目录

  • 说明
  • day21 二叉树的深度遍历的递归实现
    • 1. 二叉树的遍历
    • 2. 二叉树深度,结点数
    • 3. 代码
  • day 22 二叉树的存储
    • 1. 思路
    • 2.层次遍历代码
    • 3.代码

说明

闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata

day21 二叉树的深度遍历的递归实现

1. 二叉树的遍历

  • 前序遍历:根-左子树-右子树;
  • 中序遍历:左子树-根-右子树;
  • 后序遍历:左子树-右子树-根;
    在实现二叉树的遍历时,使用递归把把复杂的问题转化为与原来问题相似的但规模较小的问题去解决。对于二叉树采用递归是好理解的,如果二叉树的深度高了 那递归不见得就是一个高效的算法。

2. 二叉树深度,结点数

对于一颗二叉树,用递归去求二叉树的深度和结点数,不管他有多少结点,我们在理解时都把他当成一个根结点,右边一个“右结点”,左边一个“左结点”,求深度我们只需要知道是一个根结点+(看左右结点是否存在来加1),求二叉树的结点数也是,只需要关注我这个结点左右结点是否有结点。

3. 代码

  • 根据代码画出的图
    在这里插入图片描述
  • 代码
package main.java.datastructure.tree;

import java.time.OffsetDateTime;
public class BinaryCharTree {
    /**
     * The value in char
     */
    char value;

    /**
     * The left child
     */
    BinaryCharTree leftChild;

    /**
     * The right child
     */
    BinaryCharTree rightChild;

    /**
     * The first constructor
     * @param paraName
     */
    public BinaryCharTree(char paraName){
        value = paraName;
        leftChild = null;
        rightChild = null;
    }

    /**
     * manually construct a tree.
     *
     * @return
     */
    public static BinaryCharTree manualConstructTree(){
        // Step 1. Construct a tree with only one node.
        BinaryCharTree resultTree = new BinaryCharTree('a');

        //Step 2. Construct all nodes. The first node is the root.
        BinaryCharTree tempTreeB = new BinaryCharTree('b');
        BinaryCharTree tempTreeC = new BinaryCharTree('c');
        BinaryCharTree tempTreeD = new BinaryCharTree('d');
        BinaryCharTree tempTreeE = new BinaryCharTree('e');
        BinaryCharTree tempTreeF = new BinaryCharTree('f');
        BinaryCharTree tempTreeG = new BinaryCharTree('g');

        // Step 3. Link all nodes.
        resultTree.leftChild = tempTreeB;
        resultTree.rightChild = tempTreeC;
        tempTreeB.rightChild = tempTreeD;
        tempTreeC.leftChild = tempTreeE;
        tempTreeD.leftChild = tempTreeF;
        tempTreeD.rightChild = tempTreeG;

        return resultTree;
    }

    /**
     * pre-order visit
     */
    public void  preOrderVisit(){
        System.out.print("" + value + " ");

        if (leftChild != null){
            leftChild.preOrderVisit();
        }

        if (rightChild != null){
            rightChild.preOrderVisit();
        }
    }

    /**
     * in-order visit
     */
    public void  inOrderVisit(){
        if (leftChild != null){
            leftChild.inOrderVisit();
        }

        System.out.print("" + value + " ");

        if (rightChild != null) {
            rightChild.inOrderVisit();
        }
    }

    /**
     * Post-order visit.
     */
    public void postOrderVisit(){
        if (leftChild != null) {
            leftChild.postOrderVisit();
        }

        if (rightChild != null) {
            rightChild.postOrderVisit();
        }

        System.out.print("" + value + " ");
    }

    public int getDepth(){
        // It is a leaf.
        if ((leftChild == null) && (rightChild == null)) {
            return 1;
        }

        // The depth of the left child.
        int tempLeftDepth = 0;
        if (leftChild != null){
            tempLeftDepth = leftChild.getDepth();
        }

        int tempRighDepth = 0;
        if (rightChild != null){
            tempRighDepth = rightChild.getDepth();
        }

        if (tempLeftDepth >= tempRighDepth) {
            return tempLeftDepth + 1;
        }else {
            return tempRighDepth + 1;
        }
    }

    /**
     * get the number of nodes
     * @return
     */
    public int getNumNodes(){
        if (leftChild == null && rightChild == null){
            return  1;
        }

        int tempLeftNodes = 0;
        if (leftChild != null){
            tempLeftNodes = leftChild.getNumNodes();
        }

        int tempRightNodes = 0;
        if (rightChild != null) {
            tempRightNodes = rightChild.getNumNodes();
        }

        return tempLeftNodes + tempRightNodes + 1;
    }

    public static void main(String args[]) {
        BinaryCharTree tempTree = manualConstructTree();
        System.out.println("\r\nPreorder visit:");
        tempTree.preOrderVisit();
        System.out.println("\r\nIn-order visit:");
        tempTree.inOrderVisit();
        System.out.println("\r\nPost-order visit:");
        tempTree.postOrderVisit();

        System.out.println("\r\n\r\nThe depth is: " + tempTree.getDepth());
        System.out.println("The number of nodes is: " + tempTree.getNumNodes());
    }

}

在这里插入图片描述

day 22 二叉树的存储

1. 思路

(结合下图来理解将二叉树存入数组中)以完全二叉树来计算结点存储索引位置,则当双亲结点为i,则左子树存储的索引为2i+1;右子树为2i+2;如果对于稀疏的二叉树而言,用这样的存储方式显然会很浪费大量的存储空间,而文章中的第二个方法则是把存储值和存储索引分开,一个数组存储结点的值,一个数组存储结点对应的索引值,这个索引值也是根据完全二叉树计算方式算出来的,这样就可以相比于第一种方法这样可以节省空间。
在这里插入图片描述
在这里插入图片描述

2.层次遍历代码

在看了本题的存储思路主要是采用存储遍历的方式来存储二叉树的存储,所以只要层次遍历的方式明白就可以理解文章中的代码,层次遍历主要就是借助队列来实现的。以下是自己结合文章写出的层次遍历算法。

    /**
     * Level-order visit.
     */
    public void levelOderVisit(){
        CircleObjectQueue tempQueue = new CircleObjectQueue();
        tempQueue.enqueue(this);

        BinaryCharTree tempTree = (BinaryCharTree) tempQueue.dequeue();
        while (tempTree != null){
            System.out.print("" + tempTree.value + " ");

            if (tempTree.leftChild != null) {
                tempQueue.enqueue(tempTree.leftChild);
            }

            if (tempTree.rightChild != null) {
                tempQueue.enqueue(tempTree.rightChild);
            }

            tempTree = (BinaryCharTree) tempQueue.dequeue();

        }
    }

在这里插入图片描述

3.代码

我发现用前中后序遍历去实现两个队列存储貌似有点麻烦,用这个层次遍历要方便点。

    public void  toDataArrays(){
        int tempLength = getNumNodes();

        valuesArray = new char[tempLength];
        indicesArray = new int[tempLength];
        int i = 0;

        //Traverse and convert at the same time.
        CircleObjectQueue tempQueue = new CircleObjectQueue();
        tempQueue.enqueue(this);
        CircleIntQueue tempIntQueue = new CircleIntQueue();
        tempIntQueue.enqueue(0);

        BinaryCharTree tempTree = (BinaryCharTree) tempQueue.dequeue();
        int tempIndex = tempIntQueue.dequeue();
        while (tempTree != null){
            valuesArray[i] = tempTree.value;
            indicesArray[i] = tempIndex;
            i++;

            if (tempTree.leftChild != null) {
                tempQueue.enqueue(tempTree.leftChild);
                tempIntQueue.enqueue(tempIndex * 2 + 1);
            }

            if (tempTree.rightChild != null) {
                tempQueue.enqueue(tempTree.rightChild);
                tempIntQueue.enqueue(tempIndex * 2 + 2);
            }

            tempTree = (BinaryCharTree) tempQueue.dequeue();
            tempIndex = tempIntQueue.dequeue();
        }

    }

    public static void main(String args[]) {
        BinaryCharTree tempTree = manualConstructTree();
        System.out.println("\r\nPreorder visit:");
        tempTree.preOrderVisit();
        System.out.println("\r\nIn-order visit:");
        tempTree.inOrderVisit();
        System.out.println("\r\nPost-order visit:");
        tempTree.postOrderVisit();

        System.out.println("\r\n\r\nThe depth is: " + tempTree.getDepth());
        System.out.println("The number of nodes is: " + tempTree.getNumNodes());

        tempTree.toDataArrays();
        System.out.println("The values are: " + Arrays.toString(tempTree.valuesArray));
        System.out.println("The indices are: " + Arrays.toString(tempTree.indicesArray));
    }

}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《程序员面试金典(第6版)》面试题 10.02. 变位词组

题目描述 编写一种方法,对字符串数组进行排序,将所有变位词组合在一起。变位词是指字母相同,但排列不同的字符串。 注意:本题相对原题稍作修改 示例: 输入: ["eat", "tea", "tan", "ate&quo…

Python接口自动化测试实战详解

接口自动化测试是指通过编写程序来模拟用户的行为,对接口进行自动化测试。Python是一种流行的编程语言,它在接口自动化测试中得到了广泛应用。下面详细介绍Python接口自动化测试实战。 1、接口自动化测试框架 在Python接口自动化测试中,我们…

资源覆盖-overlay机制

1. SRO–Static resource overly(静态替换)2. RRO–Runtime resource overlay (运行时替换) 静态 RRO 1.写配置文件 以下代码显示了一个示例 AndroidManifest.xml。 <manifest xmlns:android"http://schemas.android.com/apk/res/android"package"com.exa…

【Redis】Redis基础命令集详解

文章目录【Redis01】Redis常用命令一、基础命令1、ping&#xff08;心跳命令&#xff09;2、get/set&#xff08;读写键值命令&#xff09;3、select&#xff08;切换数据库&#xff09;4、dbsize&#xff08;查看key数量&#xff09;5、flushdb&#xff08;删除当前库中所有数…

用starter实现Oauth2中资源服务的统一配置

一、前言 Oauth2中的资源服务Resource需要验证令牌&#xff0c;就要配置令牌的解码器JwtDecoder&#xff0c;认证服务器的公钥等等。如果有多个资源服务Resource&#xff0c;就要重复配置&#xff0c;比较繁锁。把公共的配置信息抽取出来&#xff0c;制成starter&#xff0c;可…

【案例实践】Python-GEE遥感云大数据分析、管理与可视化技术及多领域案例实践应用

查看原文>>>Python-GEE遥感云大数据分析、管理与可视化技术及多领域案例实践应用 目录 第一章、理论基础 第二章、开发环境搭建 第三章、遥感大数据处理基础 第四章、典型案例操作实践 第五章、输入输出及数据资产高效管理 第六章、云端数据论文出版级可视化 随…

图片懒加载及Vue自定义图片懒加载指令

文章目录监听滚动的方式IntersectionObserver方式自定义图片懒加载vue指令1自定义图片懒加载vue指令2lazyLoadImage.jsmain.js中注册指令组件中使用学习链接&#xff1a;前端必会的图片懒加载vue自定义指令实现图片懒加载监听滚动的方式 img的src先都用一张默认的图片&#xf…

论文推荐:DCSAU-Net,更深更紧凑注意力U-Net

这是一篇23年发布的新论文&#xff0c;论文提出了一种更深、更紧凑的分裂注意力的U-Net&#xff0c;该网络基于主特征守恒和紧凑分裂注意力模块&#xff0c;有效地利用了底层和高层语义信息。 DCSAU-Net 1、架构 DCSAU-Net 的编码器首先使用 PFC 策略从输入图像中提取低级语义…

适用于 Windows 11/1 0电脑的 8 款最佳免费数据恢复软件

在这个数字办公时代&#xff0c;我们总是在电脑前工作&#xff0c;处理海量数据&#xff0c;存储重要文件。然而&#xff0c;系统崩溃、病毒攻击或人为错误都会导致极度绝望的数据丢失。此时&#xff0c;专业的数据备份和恢复工具就是不幸者的救命稻草。因此&#xff0c;这篇文…

深入剖析Compose布局, 一步步教你打造自适应UI界面

理解Compose布局 Compose 是一种基于声明式编程的 Android UI 工具包&#xff0c;它将可组合的 UI 要素视为函数&#xff0c;并使用 Kotlin DSL 进行构建和组合。Compose 还提供了相应的布局系统和一组用于嵌套和组合 UI 要素的基本函数。 Compose 的核心布局系统由两个部分组…

Windows使用Dockers+battery historian踩坑记

1、首先&#xff0c;需要翻墙。 2、然后安装Dockers&#xff0c;网上好多博客说安装Docker Toolbox&#xff0c;我亲测无效&#xff0c;卸载后安装Docker for Windows&#xff0c;安装完成后打开&#xff0c;会提示&#xff1a; Hardware assisted virtualization and data e…

Promise这样理解更简单

一、Promise小白怎么用&#xff1f;从一个故事开始吧 1、先来一段废话故事 您是一名在古老迷失城市中探险的冒险家。您身处一间装饰华丽的房间中&#xff0c;四周布满了古老的壁画和雕塑。您发现有两个通道分别通向不同的方向&#xff0c;分别是&#xff1a;一个黑暗的通道和…

Hive源码阅读环境准备

源码地址 hive源码地址在github或gitee均可以下载&#xff0c;如果没有vpn工具&#xff0c;使用gitee网速更快点。 github地址为: https://github.com:edingbrugh/hive.gitgitee地址如下: https://gitee.com/apache/hive.git环境要求 本地或远程已经安装hivejdk 8maven 3.6…

高权限注入跨库注入

简介 上篇文章中我们讲述了如何进行手工注入&#xff0c;也通过墨者学院的靶场&#xff0c;真实的感受了SQL注入的感觉。这篇文章我们将继续介绍SQL注入。 高权限注入 含义 世界上有千千万万的网站&#xff0c;我们也都知道网站需要部署在服务器上&#xff0c;但是如果一台…

C++基础知识-----命名空间

本期开始我们来对C进行学习 目录 1.C关键字 2.命名空间 3.C的输入与输出 1.C关键字 C总计63个关键字&#xff0c;C语言32个关键字 asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcase…

摘得重磅奖项,发表精彩演讲,深度参编报告!美创闪耀CSA GCR大会

4月13日&#xff0c;第六届云安全联盟大中华区大会在上海举办&#xff0c;大会由联合国数字安全联盟、上海市经济和信息化委员会、上海市委网络安全和信息化委员会办公室、上海市普陀区人民政府指导&#xff0c;云安全联盟大中华区主办。 作为零信任数据安全践行者&#xff0c;…

java银行ATM机模拟系统dzkf94

目录 摘要 I Abstract II 第1章 绪论 1 1.1 ATM简介 1 1.2 ATM发展 1 1.3 开发意义 1 1.4 论文的组成 1 1.5 本章小结 2 第2章 系统分析 3 2.1 功能需求分析 3 2.2 业务流程分析 4 2.3 数据流程分析 5 2.4 本章小结 7 第3章 系统开发技…

车载网络 - Autosar网络管理 - 常用缩写

为了方便大家日常工作中的使用和交流&#xff0c;每块专业规范或者文章中&#xff0c;都会有或多或少的缩写使用&#xff0c;然而如果一段时间没使用&#xff0c;经常会忘记这些缩写到底代表的是什么意思&#xff0c;为了方便后续内容的介绍&#xff0c;也为了我自己后面忘记后…

【数据分析之道-NumPy(四)】numpy广播机制

文章目录 专栏导读1、广播机制2、一维数组和二维数组的广播3、二维数组和三维数组的广播4、标量和数组的广播5、形状不兼容的数组不能进行广播专栏导读 ✍ 作者简介:i阿极,CSDN Python领域新星创作者,专注于分享python领域知识。 ✍ 本文录入于《数据分析之道》,本专栏针对…

MySQL---数据类型

文章目录前言一、数据类型分类二、数值类型1.tinyint类型2.bit类型三、小数类型1.float2. decimal三、字符串类型1.char2.varchar3.char和varchar比较四、日期和时间类型五、enum和set我们如何找到性别是男或者女呢?我们如何找到爱好有rapper呢?总结前言 正文开始!!! 一、数…