Java数据结构06——树

news2024/11/26 0:37:02

1.why:

数组&链表&树

 

 

2. 大纲

 

2.1前中后序

public class HeroNode {
    private int no;
    private String name;
    private  HeroNode left;//默认为null
    private HeroNode right;//默认为null

    public HeroNode(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public HeroNode getLeft() {
        return left;
    }

    public void setLeft(HeroNode left) {
        this.left = left;
    }

    public HeroNode getRight() {
        return right;
    }

    public void setRight(HeroNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
    //遍历
    //编写前序遍历方法,被谁调用this就是谁
    public void preOrder(){
        System.out.println(this);//先输出父节点
        //递归先左子树前遍历
        if(this.left!=null){
            this.left.preOrder();
        }
        //递归向右子树前序遍历
        if (this.right!=null){
            this.right.preOrder();
        }
    };

    //编写中序遍历方法
    public void infixOrder(){
        //递归先左子树前遍历
        if(this.left!=null){
            this.left.infixOrder();
        }
        //再输出父节点
        System.out.println(this);
        //递归向右子树前序遍历
        if (this.right!=null){
            this.right.infixOrder();
        }
    };

    //编写后序遍历方法
    public void postOrder(){
        //递归先左子树前遍历
        if(this.left!=null){
            this.left.postOrder();
        }
        //递归向右子树前序遍历
        if (this.right!=null){
            this.right.postOrder();
        }
        //最后输出父节点
        System.out.println(this);
    };

  

}

2.2查找节点

 //查找
    //前序查找
    public HeroNode preSearch(int HeroNo){
        //判断当前节点是不是
        if (this.getNo()==HeroNo){
            return this;
        };
        //左子树前序查找
        //如果左递归前序查找节点,找到结点,则返回
        HeroNode resNode = null;//辅助节点

        if (this.getLeft()!=null) {
            resNode =this.getLeft().preSearch(HeroNo);
        }
        //resNode不为空才返回,因为右子树仍未查找
        if (resNode!=null){
            return resNode;
        }
        if (this.getRight()!=null){
            resNode = this.getRight().preSearch(HeroNo);
        }
        return resNode;
    }

    //中序查找
    public HeroNode infixSearch(int HeroNo){

        //左子树前序查找
        //如果左递归前序查找节点,找到结点,则返回
        HeroNode resNode = null;//辅助节点

        if (this.getLeft()!=null) {
            resNode =this.getLeft().preSearch(HeroNo);
        }
        //resNode不为空才返回,因为右子树仍未查找
        if (resNode!=null){
            return resNode;
        };
        //判断当前节点是不是
        if (this.getNo()==HeroNo){
            return this;
        }
        //查找右子树
        if (this.getRight()!=null){
            resNode = this.getRight().preSearch(HeroNo);
        }
        return resNode;
    }

    //后序查找
    public HeroNode postSearch(int HeroNo){
        //左子树前序查找
        //如果左递归前序查找节点,找到结点,则返回
        HeroNode resNode = null;//辅助节点
        if (this.getLeft()!=null) {
            resNode =this.getLeft().preSearch(HeroNo);
        }
        //resNode不为空才返回,因为右子树仍未查找
        if (resNode!=null){
            return resNode;
        };
        if (this.getRight()!=null){
            resNode = this.getRight().preSearch(HeroNo);
        }
        if (resNode!=null){
            return resNode;
        };
        //最后判断当前节点是不是
        if (this.getNo()==HeroNo){
            return this;
        };
        return resNode;
    }

2.3删除节点(基本) 

//删除
    public void deleteNode(int HeroNo){
        //判断左子节点
        if (this.left!=null && this.left.getNo()==HeroNo){
            this.left=null;
            return;
        }
        //判断右子节点
        if (this.right!=null&&this.right.getNo()==HeroNo){
            this.right=null;
            return;
        }
        //遍历左子树
        if (this.left!=null){
            this.left.deleteNode(HeroNo);
        }
        if(this.right!=null){
            this.right.deleteNode(HeroNo);
        }
    }

2.4二叉树 (root节点)

public class BinaryTree {
    //root
    private HeroNode root;

    public void setRoot(HeroNode root) {
        this.root = root;
    };
    //遍历二叉树
    //前序遍历
    public void preOrder(){
        if (this.root!=null){
            this.root.preOrder();
        }else {
            System.out.println("二叉树为空");
        }
    }

    //中序遍历
    public void infixOrder(){
        if (this.root!=null){
            this.root.infixOrder();
        }else {
            System.out.println("二叉树为空");
        }
    }

    //后续遍历
    public void postOrder(){
        if (this.root!=null){
            this.root.postOrder();
        }else {
            System.out.println("二叉树为空");
        }
    }

    //查找二叉树指定节点
    //前序查找
    public HeroNode preSearch(int HeroNo){
        if (this.root!=null){
            return this.root.preSearch(HeroNo);
        }else {
            return null;
        }
    }
    //中序查找
    public HeroNode infixSearch(int HeroNo){
        if (this.root!=null){
            return this.root.infixSearch(HeroNo);
        }else {
            return null;
        }
    }
    //后序查找
    public HeroNode postSearch(int HeroNo){
        if (this.root!=null){
            return this.root.postSearch(HeroNo);
        }else {
            return null;
        }
    }
    public void delNode(int HeroNo){
        if(root!=null){
            if (root.getNo()==HeroNo){
                root=null;
            }else {
                root.deleteNode(HeroNo);
            }
        }else {
            System.out.println("空树,无法删除");
        }
    }
}

2.5顺序存储二叉树  (为完全二叉树,公式

public class ArrBinaryTree {

    private int [] arr;//存储结点的数组

    public ArrBinaryTree(int[] arr) {
        this.arr = arr;
    }
    //重载
    public void preOrder(){
        preOrder(0);
    }
    public void infixOrder(){
        infixOrder(0);
    }
    /**
     *
     * @param index  arr[index]=i
     */
    //前序
    public void preOrder(int index){
        if(arr == null ||arr.length==0){
            System.out.println("数组为空");
        }
        System.out.println(arr[index]);
        //向左递归遍历
        if ((index*2+1)<arr.length){
            preOrder(2*index+1);

        }
        //向右递归遍历
        if ((index*2+2)<arr.length){
            preOrder(2* index+2);
        }
    }
    //中序
    public void infixOrder(int index){
        if(arr == null ||arr.length==0){
            System.out.println("数组为空");
        }
        //向左递归遍历
        if ((index*2+1)<arr.length){
            infixOrder(index*2+1);
        }
        System.out.println(arr[index]);
        //向右递归遍历
        if ((index*2+2)<arr.length){
            infixOrder(2* index+2);
        }
    }
}

 2.6线索化二叉树(节点左右节点类型、前驱指针

 

 

public class ThreadBinaryTree {
    private HeroNode root;

    //为了实现线索化,需要创建要给指向当前结点的前驱结点的指针
    // 在递归进行线索化时,pre总是保留前一个结点
    //pre指针
    private HeroNode pre =null;

    public HeroNode getRoot() {
        return root;
    }

    public HeroNode getPre() {
        return pre;
    }

    public void setPre(HeroNode pre) {
        this.pre = pre;
    }

    public void setRoot(HeroNode root) {
        this.root = root;
    };
    //重载threadNodes()
    public void threadedNodes(){
        this.threadedNodes(root);
    }



    /*多回顾*/
//    //中序线索化二叉树
    public void threadedNodes(HeroNode node){
        //递归找到最左节点,然后返回
        if (node == null) {
            return;
        }
        //先线索化左子树
        threadedNodes(node.getLeft());

        //线索化当前节点
        if (node.getLeft()==null){
            node.setLeft(pre);
            node.setLeftType(1);
        }
        //key!!!
        if (pre!=null&&pre.getRight()==null){
            pre.setRight(node);
            pre.setRightType(1);
        }
        pre=node;

        //线索化右子树
        threadedNodes(node.getRight());

    };

    //***提高:中序、后序***
    //遍历线索化二叉树
    public void threadedList(){
        HeroNode node = root;
        while (root!=null){
            while(node!=null){
                //循环的找到leftType ==1的结点,第一个找到就是8结点
                // 后面随着遍历而变化,因为当leftType==1时,说明该结点是按照线索化
                // 处理后的有效结点
                while (node.getLeftType()==0){
                    node=node.getLeft();
                }
                System.out.println(node);
                while (node.getRightType()==1){
                    node=node.getRight();
                    System.out.println(node);
                }
                //替换这个遍历点(对于原本就有右结点的)!!!
                node=node.getRight();
            }
        }
    }

    //遍历二叉树
    //前序遍历
    public void preOrder(){
        if (this.root!=null){
            this.root.preOrder();
        }else {
            System.out.println("二叉树为空");
        }
    }

    //中序遍历
    public void infixOrder(){
        if (this.root!=null){
            this.root.infixOrder();
        }else {
            System.out.println("二叉树为空");
        }
    }

    //后续遍历
    public void postOrder(){
        if (this.root!=null){
            this.root.postOrder();
        }else {
            System.out.println("二叉树为空");
        }
    }

    //查找二叉树指定节点
    //前序查找
    public HeroNode preSearch(int HeroNo){
        if (this.root!=null){
            return this.root.preSearch(HeroNo);
        }else {
            return null;
        }
    }
    //中序查找
    public HeroNode infixSearch(int HeroNo){
        if (this.root!=null){
            return this.root.infixSearch(HeroNo);
        }else {
            return null;
        }
    }
    //后序查找
    public HeroNode postSearch(int HeroNo){
        if (this.root!=null){
            return this.root.postSearch(HeroNo);
        }else {
            return null;
        }
    }
    public void delNode(int HeroNo){
        if(root!=null){
            if (root.getNo()==HeroNo){
                root=null;
            }else {
                root.deleteNode(HeroNo);
            }
        }else {
            System.out.println("空树,无法删除");
        }
    }
}

 

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

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

相关文章

AWTK 串口屏开发(1) - Hello World

1. 功能 这个例子很简单&#xff0c;制作一个调节温度的界面。在这里例子中&#xff0c;模型&#xff08;也就是数据&#xff09;里只有一个温度变量&#xff1a; 变量名数据类型功能说明温度整数温度。范围 (0-100) 摄氏度 2. 创建项目 从模板创建项目&#xff0c;将 hmi/…

快速学会绘制Pyqt5中的所有图(上)

Pyqt5相关文章: 快速掌握Pyqt5的三种主窗口 快速掌握Pyqt5的2种弹簧 快速掌握Pyqt5的5种布局 快速弄懂Pyqt5的5种项目视图&#xff08;Item View&#xff09; 快速弄懂Pyqt5的4种项目部件&#xff08;Item Widget&#xff09; 快速掌握Pyqt5的6种按钮 快速掌握Pyqt5的10种容器&…

EasyExcel之文件导出最佳实践

文件导出 官方文档&#xff1a;写Excel | Easy Excel (alibaba.com) 引言 当使用 EasyExcel 进行 Excel 文件导出时&#xff0c;我最近在工作中遇到了一个需求。因此&#xff0c;我决定写这篇文章来分享我的经验和解决方案。如果你对这个话题感兴趣&#xff0c;那么我希望这篇…

【Linux系统化学习】进程地址空间 | 虚拟地址和物理地址的关系

个人主页点击直达&#xff1a;小白不是程序媛 Linux专栏&#xff1a;Linux系统化学习 代码仓库&#xff1a;Gitee 目录 虚拟地址和物理地址 页表 进程地址空间 进程地址空间存在的意义 虚拟地址和物理地址 我们在学习C/C的时候肯定都见过下面这张有关于内存分布的图片&a…

Flameshot的安装、配置及使用

概要&#xff1a;本篇主要介绍在Ubuntu22.04环境下&#xff0c;截图软件Flameshot的安装、配置及使用。 一、安装 推荐命令行安装 sudo apt install flameshot 二、修改gdm3配置文件 这一步是为了解决截图时没有光标的问题&#xff0c;解决方法我是从这里学到的解决flam…

【Linux】如何清空某个文件的内容

cat /dev/null > file1 清空某个文件的内容使用cat /dev/null > file1&#xff0c;它将 /dev/null 的内容&#xff08;空内容&#xff09;重定向到 file1。 如下所示&#xff0c;file1文件里的内容被清空。 错误写法 错误写法是&#xff1a;cat file1 > /dev/null&…

LeetCode Hot100 131.分割回文串

题目&#xff1a; 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 回文串 是正着读和反着读都一样的字符串。 方法&#xff1a;灵神-子集型回溯 假设每对相邻字符之间有个逗号&#xff0c;那么就看…

高效的多维空间点索引算法——GeoHash

一、Geohash 算法简介 GeoHash是空间索引的一种方式&#xff0c;其基本原理是将地球理解为一个二维平面&#xff0c;通过把二维的空间经纬度数据编码为一个字符串&#xff0c;可以把平面递归分解成更小的子块&#xff0c;每个子块在一定经纬度范围内拥有相同的编码。以GeoHash方…

leetcode面试经典150题——35 螺旋矩阵

题目&#xff1a; 螺旋矩阵 描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 提示&…

P4 Qt如何添加qss样式表文件和添加图片资源

目录 前言 01 添加图片资源文件 02 添加qss文件 前言 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Qt基础_ChenPi的博客-CSDN博客》✨✨✨ &#x1f33a;本篇简介 &#xff1a;这一章…

【STM32】蓝牙氛围灯

Docs 一、项目搭建和开发流程 一、项目需求和产品定义 1.需求梳理和产品定义 一般由甲方公司提出&#xff0c;或由本公司市场部提出 需求的重点是&#xff1a;这个产品究竟应该做成什么样&#xff1f;有哪些功能&#xff1f;具体要求和参数怎样&#xff1f;此外还要考虑售价…

Advanced Renamer

Advanced Renamer 安装链接 1.前后添加字符 2.字符转数字&#xff0c;编号整体加减

混合预编码(Hybrid Precoding)的全连接结构与子连接结构

A Survey on Hybrid Beamforming Techniques in 5G: Architecture and System Model Perspectives 全连接结构的混合预编码 子连接结构的混合预编码 Alternating Minimization Algorithms for HybridPrecoding in Millimeter Wave MIMO Systems

Rust测试字符串的移动,Move

代码创建了一个结构体&#xff0c;结构体有test1 字符串&#xff0c;还有指向字符串的指针。一共创建了两个。 然后我们使用swap 函数 交换两个结构体内存的内容。 最后如上图。相同的地址&#xff0c;变成了另外结构体的内容。注意看指针部分&#xff0c;还是指向原来的地址…

HttpComponents: 概述

文章目录 1. 概述2. 生态位 1. 概述 早期的Java想要实现HTTP客户端需要借助URL/URLConnection或者自己手动从Socket开始编码&#xff0c;需要处理大量HTTP协议的具体细节&#xff0c;不但繁琐还容易出错。 Apache Commons HttpClient的诞生就是为了解决这个问题&#xff0c;它…

【C++】仿函数在模板中的应用——【默认模板实参】详解(n)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.引入&#xff1a;查看(容器)文档时常…

UE4 材质实现Glitch效果

材质实现Glitch效果 UE4 材质实现Glitch效果预览1预览2 UE4 材质实现Glitch效果 预览1 添加材质函数&#xff1a; MF_RandomNoise 添加材质&#xff1a; 预览2 添加材质函数MF_CustomPanner&#xff1a; 添加材质函数&#xff1a;MF_Glitch 材质添加&#xff1a; 下面用…

免费的网页数据抓取工具有哪些?【2024附下载链接】

在网络上&#xff0c;有许多网页数据抓取工具可供选择。本文将探讨其如何全网采集数据并支持指定网站抓取。我们将比较不同的数据采集工具&#xff0c;帮助您找到最适合您需求的工具。 网页数据抓取工具种类 在选择网页数据抓取工具之前&#xff0c;让我们先了解一下这些工具…

基于单片机音乐盒仿真仿真系统设计

**单片机设计介绍&#xff0c;基于单片机音乐盒仿真仿真系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的音乐盒仿真仿真系统是一种基于嵌入式系统技术的设计方案&#xff0c;用于模拟传统的音乐盒功能。它通…

pyside/qt03——人机协同的编程教学—直接面向chatGPT实战开发(做中学,事上练)

先大概有个草图框架&#xff0c;一点点丰富 我纠结好久&#xff0c;直接用Python写UI代码 还是用designer做UI 再转Python呢&#xff0c; 因为不管怎么样都要转成Python代码&#xff0c; 想了想还是学一下designer吧&#xff0c;有个中介&#xff0c;有直观理解。 直接这样也可…