数据结构—树、有序二叉树

news2024/9/21 18:57:40

文章目录

  • 树的概述
  • 树的分类
  • 二叉树的遍历
  • 有序二叉树代码
    • 通过链表方式构建有序二叉树
    • 通过递归方式实现有序二叉树
    • 递归遍历有序二叉树
      • 中序遍历:
      • 先序遍历:
      • 后序遍历:
  • 删除节点
    • 1、删除叶子节点
      • 删除叶子节点总结图示
    • 2、删除只有一个子树的节点
      • 删除只有一个子树的节点总结图示
    • 3、删除有两个子树的节点
      • 删除有两个子树的节点总结图示

————————————————————————————————

树的概述

树——>链式存储结构
注:
数组:查询简单,插入删除复杂
链表:增删改简单,查询复杂
树:即保证查找速度,又保证增删改速度根节点比要查找的数大的话,相当于根节点右边的树可以不需要查询,类似于二分查找

树的分类

在这里插入图片描述

二叉树的遍历

在这里插入图片描述
例:
在这里插入图片描述

有序二叉树代码

有序二叉树特点:左子节点的值小于父节点,右子节点的值大于父节点
在这里插入图片描述
在这里插入图片描述
(1)首先5做根节点,7和5比较,7比5大则作为5的右子节点;
(2)4和5比较,4比5小则作为5的左子节点;
(3)2和5比较,2比5小,则向左走,5右左子节点4,2和4比较,2比4小且4没有左子节点,则2作为4的左子节点;
(4)向后重复上述步骤

通过链表方式构建有序二叉树

—1—>创建类,创建管理类,创建新节点newNode,创建指向根节点的变量root
—2—>如果root为空,将newNode放再root上面
—3—>当root不为空时,定义游标p指向root,准备向后遍历二叉树
—4—>newNode和游标p指向的根节点进行值得比较,newNode小则向左走,newNode大则向右走
—5—>判断现在p指向是否为空,p不为空则表示有左(右)子节点,继续让newNode和p指向的节点判断大小;p为空则插入数据
—6—>p当前指向为空,该如何解决插入数据得问题?=>定义另一个游标pre指向p游标得前一个节点
—7—>在每次循环时让pre指向p当前指向的节点,后面p向后走时,pre指向不动;因为p向下走一步且指向不为空时,会进行while循环,pre再次指向p,而此时p已经指向下一个了,所以pre始终指向p的前一个。
—8—>有了pre指向p的前一个节点,因此当p指向空时,给pre的左(右)节点赋值,就完成了节点的插入操作

import java.util.LinkedList;

public class BinaryTree{
    TreeNode root;
    /*
     * 【1】构建有序二叉树
    * */
    public void insert(int value) {//传值
    //新建节点
    TreeNode newNode=new TreeNode(value);
    //判断树是否为空
    //为空
    if(root == null) {
root=newNode;
    }else {
    //不为空
    //定义游标,游标1和pre游标
        TreeNode currentNode=root;
        TreeNode parentNode = null;
//循环操作比较
while(true) {
    parentNode=currentNode;//parentNode指向游标1指向的节点
             //判断新节点的值和当前节点的值大小
    if(newNode.getValue()<currentNode.getValue()) {//新节点值大时
currentNode=currentNode.getLeftTreeNode();//游标向
    if(currentNode==null) {
parentNode.setLeftTreeNode(newNode);
    return;
    }

            }else {
currentNode=currentNode.getRightTreeNode();
if(currentNode == null) {
    parentNode.setRightTreeNode(newNode);
    return;
}
    }
}//while

    }//else
    }//insert
}

通过递归方式实现有序二叉树

import java.util.LinkedList;

public class BinaryTree{
    TreeNode root;
/*
 * 【2】递归实现树
 * 
*/

    public void DiguiInsert(TreeNode node,int value) {
TreeNode newNode = new TreeNode(value);
if(root==null) {
    root=newNode;
    return;
}
//当前节点和新节点比较
if(node.getValue()>newNode.getValue()) {//左
//判断当前节点左子树是否为空
    if(node.getLeftTreeNode() != null) {
    //当前节点左子树不为空继续调用方法,进行比较
DiguiInsert(node.getLeftTreeNode(), value);

    }else {
    //当前节点左子树为空就添加
    node.setLeftTreeNode(newNode);
    }
}else {//右
//判断当前节点右子树是否为空
    if(node.getRightTreeNode() != null) {
    //当前节点右子树不为空继续调用方法,进行比较
DiguiInsert(node.getRightTreeNode(), value);
    }else {
//当前节点右子树为空就添加
node.setRightTreeNode(newNode);

    }
        }
    }
}

递归遍历有序二叉树

中序遍历:

先向左进行遍历,直到节点没有子树的时候输出,方法出栈,这样就回到上一个节点;
节点再输出后看有没有右子树,有就输出,没有就再返回上一个节点

递归方程式:向左走时:midOrder(node)= midOrder(node.left)

public void midOrder(TreeNode treeNode) {
    if(treeNode==null) {
return;
    }

    midOrder(treeNode.getLeftTreeNode());
    System.out.println(treeNode.getValue());
    midOrder(treeNode.getRightTreeNode());
}

先序遍历:

先输出节点,再向左进行遍历,直到节点没有子树的时候输出,方法出栈,这样就回到上一个节点,输出节点,节点再输出后看有没有右子树,有就输出,没有就再返回上一个节点。

public void beforeOrder(TreeNode treeNode) {
    if(treeNode==null) {
    return;
    }
    System.out.println(treeNode.getValue());
    beforeOrder(treeNode.getLeftTreeNode());
    beforeOrder(treeNode.getRightTreeNode());
}

后序遍历:

先向左进行遍历,直到节点没有子树的时候输出,方法出栈,再向右进行遍历,直到节点没有子树的时候输出,方法出栈,这样就回到上一个节点,输出节点。

public void afterOrder(TreeNode treeNode) {
    if(treeNode==null) {
        return;
    }

    afterOrder(treeNode.getLeftTreeNode());
    afterOrder(treeNode.getRightTreeNode());
    System.out.println(treeNode.getValue());

}

删除节点

1、删除叶子节点

(1)找到要删除的节点targetNode
(2)找到要删除的节点的父节点parentNode
(3)确定targetNode是parentNode的左子树还是右子树
(4)根据第3点进行删除
targetNode是左子节点:parentNode.setleftTreeNode(null)
targetNode是右子节点:parentNode.setrightTreeNode(null)

删除叶子节点总结图示

在这里插入图片描述

2、删除只有一个子树的节点

(1)找到要删除的节点targetNode
(2)找到要删除的节点的父节点parentNode
(3)确定targetNode是parentNode的左子树还是右子树
(4)确定targetNode有左子树还是右子树
(5)如果targetNode有左子树
(5.1)如果targetNode是parentNode的左子树:parentNode.left=targetNode.left
(5.2)如果targetNode是parentNode的右子树:parentNode.right=targetNode.left
(6)如果targetNode有右子树
(6.1)如果targetNode是parentNode的左子树:parentNode.left=targetNode.right
(6.2)如果targetNode是parentNode的右子树:parentNode.right=targetNode.right

删除只有一个子树的节点总结图示

在这里插入图片描述

3、删除有两个子树的节点

(1)找到要删除的节点targetNode
(2)找到要删除的节点的父节点parentNode
(3)找到targetNode右子树的最小值(左子树的最大值)temp
(4)用temp替换要删除的节点值
(5)删除右子树的最小值(左子树的最大值)

删除有两个子树的节点总结图示

在这里插入图片描述

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

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

相关文章

毕业设计-基于深度学习火灾烟雾检测识别系统-yolo

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着准备考研,考公,考教资或者实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过…

Spring循环依赖源码解析(深度理解)

文章目录前言本章目标一、什么是循环依赖&#xff1f;1、那么循环依赖是个问题吗&#xff1f;2、但是在Spring中循环依赖就是一个问题了&#xff0c;为什么&#xff1f;二、Bean的生命周期2.1、在Spring中&#xff0c;Bean是如何生成的&#xff1f;2.2、那么这个注入过程是怎样…

GitLab CI/CD系列教程(一)

来自&#xff1a;GitLab CI/CD系列教程&#xff08;一&#xff09;&#xff1a;Docker安装GitLab_哔哩哔哩_bilibili 1. 创建虚拟机并连接Xterm 创建一个4G内存的虚拟机&#xff0c;否则很容易启动不了&#xff0c;报502 虚拟机的创建看这篇&#xff1a; VMware16的安装及VM…

基于java+ssm+vue+mysql的网上书店

项目介绍 本网上系统是针对目前网上的实际需求&#xff0c;从实际工作出发&#xff0c;对过去的网上系统存在的问题进行分析&#xff0c;结合计算机系统的结构、概念、模型、原理、方法&#xff0c;在计算机各种优势的情况下&#xff0c;采用目前最流行的B/S结构和java中流行的…

从0开始搭建vue2管理后台基础模板

网站主要完成&#xff1a;侧边菜单栏、页面标签卡、内容栏 源代码gitee地址&#xff1a;https://gitee.com/zhao_liangliang1997/navigation-bar 一、起步 1、创建vue项目 vue create 项目名2、引入element 3、其他安装 1、首先需要安装如下 cnpm install vuex cnpm install…

DockerCompose安装、使用 及 微服务部署实操

1 什么是DockerCompose DockerCompose是基于Compose文件帮助我们快速的部署分布式应用。 解决容器需手动一个个创建和运行的问题&#xff01; DockerCompose本质上也是一个文本文件&#xff0c;其通过指令定义集群中的每个容器如何运行。我们可以将其看做是将多个docker run…

Ansible 自动化运维工具的使用

目录 一、Ansible简介 二、Ansible 的安装和使用 1.下载 2.使用 三、Ansible命令和模块 1.命令格式 2.命令行模块 &#xff08;1&#xff09;command 模块 &#xff08;2&#xff09;shell 模块 &#xff08;3&#xff09;cron 模块 &#xff08;4&#xff09;user …

多线程 3

多线程 3 : 文章目录1.线程安全2. 产生线程安全的原因3. synchronized - 加锁操作4.可重入5.死锁问题6. volatile 关键字7.wait 和 notify1.线程安全 为啥会出现线程安全 &#xff1f;   罪魁祸首&#xff0c;还是多线程的抢占式执行&#xff0c; 正因为抢占式执行&#xff0c…

Java项目:SSM场地预订管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;前台为普通用户登录&#xff0c;后台为管理员登录&#xff1b; 用户角色包含以下功能&#xff1a; 按分类查看场…

【车载开发系列】UDS诊断---通信控制($0x28)

【车载开发系列】UDS诊断—通信控制&#xff08;$0x28&#xff09; UDS诊断---通信控制&#xff08;$0x28&#xff09;【车载开发系列】UDS诊断---通信控制&#xff08;$0x28&#xff09;一.概念定义二.实现原理三.应用场景四.子功能五.报文格式1&#xff09;请求报文2&#xf…

自动导入指定文件夹内的文献到 Endnote 中

简介 最近正着手写一篇综述文章&#xff0c;来整体把握下自己研究领域的历史、方法、最新进展与趋势。由于需要对相关文献进行搜集、阅读和分类。庄小编使用 EndNote 来进行管理文献。 在使用较长时间后&#xff0c;整理了几个超级好用的小技巧。比如&#xff1a;自动导入指定…

pikachu靶场-upload-速通

upload-速通client checkMIME typegetimagesizeclient check 最简单的&#xff0c;先上传一张含有一句话木马的图片&#xff0c;抓包修改图片后缀为php&#xff0c;放包发送就行 访问并确认该上传文件是否以php形式解析 蚁剑直连&#xff1a; MIME type 后端php检查上传文…

基于MSER的高速公路交通标志提取matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 自然场景下的文本检测是自然场景图像信息提取的基础,在车牌识别、实时翻译、图像检索等领域具有广泛的应用价值及研究意义。基于连通区域的方法是自然场景文本检测中最为常见的方法,其中最大稳定…

[附源码]Python计算机毕业设计SSM街舞公司管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Java Script 内置对象(三) --------- Array 对象

判断是否为数组有两种方式&#xff0c;instanceof 和 Array.isArray( 参数 )&#xff0c;两者判断方法均为如果是数组则返回 true&#xff0c;不是数组则返回 **false&#xff0c;**其中第二个方法为H5新增加的方法 var arr[]; var obj{}; console.log(arr instanceof Arra…

微服务入门案例

boot与cloud版本 springboot:提供了快速开发微服务的能力 springcloud提供了微服务治理的能力&#xff08;服务注册与发现、服务降级、限流、熔断、网关、负载均衡、配置中心...&#xff09;&#xff0c;为微服务开发提供了全家桶服务 springboot的版本查看地址&#xff1a;Spr…

云原生之Docker简介和环境准备

Docker简介一、主机环境二、Docker 安装三、Docker简介3.1、Docker解决的问题3.2、Docker技术边界3.3、Docker带来的改变3.4、Docker和虚拟机的区别3.5、Docker 架构图3.6、直观感受client请求server总结后言一、主机环境 &#xff08;1&#xff09;ubuntu-20.04.4-live-serve…

【torch.utils.data】 Dataset和Dataloader的解读和使用

文章目录torch.utils.data前言DatasetDataloader实践参考torch.utils.data 前言 Pytorch中的 torch.utils.data 提供了两个抽象类&#xff1a;Dataset 和 Dataloader。Dataset 允许你自定义自己的数据集&#xff0c;用来存储样本及其对应的标签。而 Dataloader 则是在 Datase…

LTspice XVII > Transformer 变压器仿真

目录 第①步设置 第②步设置 第③步设置 第④步设置 输出结果 最近在看“无线电基础电路实作修订版 [&#xff08;美&#xff09;西尔弗 著] 2014年版”这本书&#xff0c;打算好好修炼下无线电方面的基础知识&#xff0c;让自己更加牛逼一些&#xff0c;工作中偶尔可以装…

指标与标签的区别?

概述 在公司数据建设过程中&#xff0c;经常会使用和提到指标和标签&#xff0c;但是很多小伙伴对于两者的区别确不能讲清楚。实际上标签与指标一样&#xff0c;是理解数据的两种方式&#xff0c;在赋能业务上&#xff0c;两者同样重要。接下来将结合自身的理解&#xff0c;从…