多叉树的构建,条件查询,修改删除节点

news2025/2/1 4:08:03

多叉树的构建查询,新增,修改,删除

文章目录

  • 多叉树的构建查询,新增,修改,删除
    • 一,数据库表设计
    • 二、新增相对应数据库表的实体类
    • 三、新建多叉树树工具类
    • 四、多叉树树的条件查询
    • 五、多叉树的节点新增
    • 六、多叉树的节点删除
    • 七、多叉树修改

一,数据库表设计

一般树型的节点信息管理表只需要一个id(当前节点id)以及一个parent_id(父节点id即可),其他的基础信息字段按照需求来

注意这里我 给parent_id字段设置了默认值-1,代表不在这颗树中,parent_id为0即代表为根节点。

例如这里一个管理模块对这张表进行了维护,可新增节点2和可新增节点3都目前都不在这棵树中但是后续可以把它添加到树中(添加的时候只查询parent_id为-1的数据,表示这些数据可作为节点新增到树中,新增其实就是前端传id和parent_id,然后根据id更新掉parent_id即可)

二、新增相对应数据库表的实体类

实体类的这部分代码逻辑都差不多,这里的代码是参考下面这篇博客的代码:

多叉树操作博客

public class TreeNode implements Serializable {  
    private int parentId;  
    private int selfId;  
    protected String nodeName;  
    protected Object obj;  
    protected TreeNode parentNode;  
    protected List<TreeNode> childList;  
  
    public TreeNode() {  
        initChildList();  
    }  
  
    public TreeNode(TreeNode parentNode) {  
        this.getParentNode();  
        initChildList();  
    }  
  
    public boolean isLeaf() {  
        if (childList == ) {  
            return true;  
        } else {  
            if (childList.isEmpty()) {  
                return true;  
            } else {  
                return false;  
            }  
        }  
    }  
  
    /* 插入一个child节点到当前节点中 */  
    public void addChildNode(TreeNode treeNode) {  
        initChildList();  
        childList.add(treeNode);  
    }  
  
    public void initChildList() {  
        if (childList == )  
            childList = new ArrayList<TreeNode>();  
    }  
  
    public boolean isValidTree() {  
        return true;  
    }  
  
    /* 返回当前节点的父辈节点集合 */  
    public List<TreeNode> getElders() {  
        List<TreeNode> elderList = new ArrayList<TreeNode>();  
        TreeNode parentNode = this.getParentNode();  
        if (parentNode == ) {  
            return elderList;  
        } else {  
            elderList.add(parentNode);  
            elderList.addAll(parentNode.getElders());  
            return elderList;  
        }  
    }  
  
    /* 返回当前节点的晚辈集合 */  
    public List<TreeNode> getJuniors() {  
        List<TreeNode> juniorList = new ArrayList<TreeNode>();  
        List<TreeNode> childList = this.getChildList();  
        if (childList == ) {  
            return juniorList;  
        } else {  
            int childNumber = childList.size();  
            for (int i = 0; i < childNumber; i++) {  
                TreeNode junior = childList.get(i);  
                juniorList.add(junior);  
                juniorList.addAll(junior.getJuniors());  
            }  
            return juniorList;  
        }  
    }  
  
    /* 返回当前节点的孩子集合 */  
    public List<TreeNode> getChildList() {  
        return childList;  
    }  
  
    /* 删除节点和它下面的晚辈 */  
    public void deleteNode() {  
        TreeNode parentNode = this.getParentNode();  
        int id = this.getSelfId();  
  
        if (parentNode != ) {  
            parentNode.deleteChildNode(id);  
        }  
    }  
  
    /* 删除当前节点的某个子节点 */  
    public void deleteChildNode(int childId) {  
        List<TreeNode> childList = this.getChildList();  
        int childNumber = childList.size();  
        for (int i = 0; i < childNumber; i++) {  
            TreeNode child = childList.get(i);  
            if (child.getSelfId() == childId) {  
                childList.remove(i);  
                return;  
            }  
        }  
    }  
  
    /* 动态的插入一个新的节点到当前树中 */  
    public boolean insertJuniorNode(TreeNode treeNode) {  
        int juniorParentId = treeNode.getParentId();  
        if (this.parentId == juniorParentId) {  
            addChildNode(treeNode);  
            return true;  
        } else {  
            List<TreeNode> childList = this.getChildList();  
            int childNumber = childList.size();  
            boolean insertFlag;  
  
            for (int i = 0; i < childNumber; i++) {  
                TreeNode childNode = childList.get(i);  
                insertFlag = childNode.insertJuniorNode(treeNode);  
                if (insertFlag == true)  
                    return true;  
            }  
            return false;  
        }  
    }  
  
    /* 找到一颗树中某个节点 */  
    public TreeNode findTreeNodeById(int id) {  
        if (this.selfId == id)  
            return this;  
        if (childList.isEmpty() || childList == ) {  
            return ;  
        } else {  
            int childNumber = childList.size();  
            for (int i = 0; i < childNumber; i++) {  
                TreeNode child = childList.get(i);  
                TreeNode resultNode = child.findTreeNodeById(id);  
                if (resultNode != ) {  
                    return resultNode;  
                }  
            }  
            return ;  
        }  
    }  
  
    /* 遍历一棵树,层次遍历 */  
    public void traverse() {  
        if (selfId < 0)  
            return;  
        print(this.selfId);  
        if (childList ==  || childList.isEmpty())  
            return;  
        int childNumber = childList.size();  
        for (int i = 0; i < childNumber; i++) {  
            TreeNode child = childList.get(i);  
            child.traverse();  
        }  
    }  
  
    public void print(String content) {  
        System.out.println(content);  
    }  
  
    public void print(int content) {  
        System.out.println(String.valueOf(content));  
    }  
  
    public void setChildList(List<TreeNode> childList) {  
        this.childList = childList;  
    }  
  
    public int getParentId() {  
        return parentId;  
    }  
  
    public void setParentId(int parentId) {  
        this.parentId = parentId;  
    }  
  
    public int getSelfId() {  
        return selfId;  
    }  
  
    public void setSelfId(int selfId) {  
        this.selfId = selfId;  
    }  
  
    public TreeNode getParentNode() {  
        return parentNode;  
    }  
  
    public void setParentNode(TreeNode parentNode) {  
        this.parentNode = parentNode;  
    }  
  
    public String getNodeName() {  
        return nodeName;  
    }  
  
    public void setNodeName(String nodeName) {  
        this.nodeName = nodeName;  
    }  
  
    public Object getObj() {  
        return obj;  
    }  
  
    public void setObj(Object obj) {  
        this.obj = obj;  
    }  
}  

三、新建多叉树树工具类

通过前面这三步其实就已经构建起来了一颗多叉树,以及多叉树的一些基本操作。

例如这里的TreeNode root节点其实就是已经构建好的树,并存在了这个属性中。

public class TreeHelper {  
  
    private TreeNode root;  
    private List<TreeNode> tempNodeList;  
    private boolean isValidTree = true;  
  
    public TreeHelper() {  
    }  
  
    public TreeHelper(List<TreeNode> treeNodeList) {  
        tempNodeList = treeNodeList;  
        generateTree();  
    }  
  
    public static TreeNode getTreeNodeById(TreeNode tree, int id) {  
        if (tree == )  
            return ;  
        TreeNode treeNode = tree.findTreeNodeById(id);  
        return treeNode;  
    }  
  
    /** generate a tree from the given treeNode or entity list */  
    public void generateTree() {  
        HashMap nodeMap = putNodesIntoMap();  
        putChildIntoParent(nodeMap);  
    }  
  
    /** 
     * put all the treeNodes into a hash table by its id as the key 
     *  
     * @return hashmap that contains the treenodes 
     */  
    protected HashMap putNodesIntoMap() {  
        int maxId = Integer.MAX_VALUE;  
        HashMap nodeMap = new HashMap<String, TreeNode>();  
        Iterator it = tempNodeList.iterator();  
        while (it.hasNext()) {  
            TreeNode treeNode = (TreeNode) it.next();  
            int id = treeNode.getSelfId();  
            if (id < maxId) {  
                maxId = id;  
                this.root = treeNode;  
            }  
            String keyId = String.valueOf(id);  
  
            nodeMap.put(keyId, treeNode);  
            // System.out.println("keyId: " +keyId);  
        }  
        return nodeMap;  
    }  
  
    /** 
     * set the parent nodes point to the child nodes 
     *  
     * @param nodeMap 
     *            a hashmap that contains all the treenodes by its id as the key 
     */  
    protected void putChildIntoParent(HashMap nodeMap) {  
        Iterator it = nodeMap.values().iterator();  
        while (it.hasNext()) {  
            TreeNode treeNode = (TreeNode) it.next();  
            int parentId = treeNode.getParentId();  
            String parentKeyId = String.valueOf(parentId);  
            if (nodeMap.containsKey(parentKeyId)) {  
                TreeNode parentNode = (TreeNode) nodeMap.get(parentKeyId);  
                if (parentNode == ) {  
                    this.isValidTree = false;  
                    return;  
                } else {  
                    parentNode.addChildNode(treeNode);  
                    // System.out.println("childId: " +treeNode.getSelfId()+" parentId: "+parentNode.getSelfId());  
                }  
            }  
        }  
    }  
  
    /** initialize the tempNodeList property */  
    protected void initTempNodeList() {  
        if (this.tempNodeList == ) {  
            this.tempNodeList = new ArrayList<TreeNode>();  
        }  
    }  
  
    /** add a tree node to the tempNodeList */  
    public void addTreeNode(TreeNode treeNode) {  
        initTempNodeList();  
        this.tempNodeList.add(treeNode);  
    }  
  
    /** 
     * insert a tree node to the tree generated already 
     *  
     * @return show the insert operation is ok or not 
     */  
    public boolean insertTreeNode(TreeNode treeNode) {  
        boolean insertFlag = root.insertJuniorNode(treeNode);  
        return insertFlag;  
    }  
  
    /** 
     * adapt the entities to the corresponding treeNode 
     *  
     * @param entityList 
     *            list that contains the entities 
     *@return the list containg the corresponding treeNodes of the entities 
     */  
    public static List<TreeNode> changeEnititiesToTreeNodes(List entityList) {  
        OrganizationEntity orgEntity = new OrganizationEntity();  
        List<TreeNode> tempNodeList = new ArrayList<TreeNode>();  
        TreeNode treeNode;  
  
        Iterator it = entityList.iterator();  
        while (it.hasNext()) {  
            orgEntity = (OrganizationEntity) it.next();  
            treeNode = new TreeNode();  
            treeNode.setObj(orgEntity);  
            treeNode.setParentId(orgEntity.getParentId());  
            treeNode.setSelfId(orgEntity.getOrgId());  
            treeNode.setNodeName(orgEntity.getOrgName());  
            tempNodeList.add(treeNode);  
        }  
        return tempNodeList;  
    }  
  
    public boolean isValidTree() {  
        return this.isValidTree;  
    }  
  
    public TreeNode getRoot() {  
        return root;  
    }  
  
    public void setRoot(TreeNode root) {  
        this.root = root;  
    }  
  
    public List<TreeNode> getTempNodeList() {  
        return tempNodeList;  
    }  
  
    public void setTempNodeList(List<TreeNode> tempNodeList) {  
        this.tempNodeList = tempNodeList;  
    }  
  
} 

四、多叉树树的条件查询

这里是参考我自己改写的代码,由于在云桌面里面,所以上了截图,逻辑跟上面的代码是可以衔接起来的,

比如这列构建一棵股东树,并根据股东名称对树进行查询,首先在实体类里面新加一个isRead字段默认为0,查询搜索到之后就会把它设为1,最后删除掉所有子节点中isRead为0的节点反给前端。

五、多叉树的节点新增

  • 首先根据parent_id为-1这个条件查出所有不在树中的节点数据,即可添加进树的节点

  • 根据节点id把parent_id改为前端传的父节点id即添加成功

六、多叉树的节点删除

这里做的比较简单,前端传当前节点id,删除时看有没有parent_id为当前节点id的节点,如果有则不让删除当前节点,提醒用户先删除下层节点。

七、多叉树修改

这里目前也比较简单只让他修改节点的基础信息,前端传节点id然后修改就行了。

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

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

相关文章

关于【Git】push失败与使用小乌龟(TortoiseGit)时的一些报错解决方案

1.报错:No supported authentication methods available (server sent: publickey) 原因.小乌龟没有设置git路径&#xff0c;解决如下 将红框标注的地址改为自己的git安装地址即可。 2.使用git推送到远程仓库的时候报错Failed to connect to 127.0.0.1 port 7890: 拒绝连接 …

C# 让程序代码在固定的线程里运行

一、概述 在平时我们的开发中&#xff0c;多线程也是经常用到的&#xff0c;尤其是我们做上位机行业的&#xff0c;平时更是必不可少&#xff0c;在以前我做 Unity3d 开发时&#xff0c;其实并不用关心线程的问题&#xff0c;在 Unity 的开发中&#xff0c;所有代码基本都是单…

点云综述(整理自网络资源)

目录 一、什么是点云 二、如何获取点云 1、三维激光扫描仪 2、双目相机 双目测距基本原理 视差图 双目测距的优点与难点 3、RGB-D相机 RGB-D什么意思 RGB-D相机的分类 RGBD相机的缺点&#xff1a; RGBD相机的优点 三、点云有哪些研究方向 1、基于点云的分类 2、基于…

华为OD机试真题 JavaScript 实现【IPv4地址转换成整数】【2023 B卷 100分】

一、题目描述 存在一种虚拟 IPv4 地址&#xff0c;由4小节组成&#xff0c;每节的范围为0~255&#xff0c;以#号间隔&#xff0c; 虚拟 IPv4 地址可以转换为一个32位的整数&#xff0c;例如&#xff1a; 128#0#255#255&#xff0c;转换为32位整数的结果为2147549183&#xff0…

【深入理解函数栈帧:探索函数调用的内部机制】

本章我们要介绍的不是数学中的函数&#xff0c;而是C语言中的函数哟&#xff01; 本章重点 了解汇编指令深刻理解函数调用过程 样例代码&#xff1a; #include <stdio.h> int MyAdd(int a, int b) {int c 0;c a b;return c; }int main() {int x 0xA;int y 0xB;int…

SpringCloud第二篇:Feign远程调用

思考&#xff1a;为啥要学Feign呢&#xff1f; 先来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; String url "http://userservice/user/" order.getUserId(); User user restTemplate.getFor0bject(url,User.class);这里就有几个问题&#xff1a…

首届“设计·无尽谈”论坛完满收官 持续打造当代设计共同体

首届“设计无尽谈”论坛在京举行 5月16日&#xff0c;首届“设计无尽谈”论坛在北京举行&#xff0c;本次论坛以“漫谈当代空间精神”为主题&#xff0c;12位来自顶尖建筑设计领域的嘉宾和设计师到场&#xff0c;论坛以茶话会的形式进行&#xff0c;不受严格的议程和时间限制的…

计算机网络之网络层

四.网络层&#xff1a;数据平面 4.1 网络层概述 网络层被分解为两个相互作用的部分&#xff0c;即数据平面和控制平面。 数据平面决定到达路由器输入链路之一的数据报如何转发到该路由器的输出链路之一&#xff0c;转发方式有&#xff1a; 传统的IP转发&#xff1a;转发基于…

Nginx(一)介绍Nginx、正向代理和实现反向代理的两个实例

文章目录 一、Nginx介绍二、正向代理三、反向代理四、实例演示1、反向代理实例一&#xff08;反向代理&#xff0c;访问www.123.com&#xff09;2、反向代理实例二&#xff08;使用 nginx 反向代理&#xff0c;根据访问的路径跳转到不同端口的服务中&#xff09; 五、nginx之lo…

文件操作之文件下载(32)

下载和读取是差不多的情况 区分 文件被解析&#xff0c;我们称为文件包含漏洞 显示文件的源代码&#xff0c;我们称为文件读取漏洞 提示文件下载&#xff0c;我们称为文件下载漏洞 #文件下载 文件下载出现的原因&#xff0c;在任意代码里面出现下载性的功能性函数所导致的…

调用腾讯API实现人像分割

目录 1. 作者介绍2&#xff0e;腾讯云API人像分割2.1 人像分割接口描述2.2 请求参数介绍 3&#xff0e;代码实现3.1 获取SecretId和SecretKey3.2 人像分割代码调试3.3 完整代码3.4 实验结果 1. 作者介绍 岳泽昂&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c…

MySQL主从同步——主库已有的数据如何到从库

一、复制主库数据到从库 此步骤主要针对运行一段时间的主库&#xff0c;需要将历史数据导入到从库&#xff0c;保证主从强一致性。 主库锁表停止写操作 在主库MySQL命令行中执行 flush tables with read lock; 主库数据导出 将主库所在主机命令行下使用mysqldump命令导出…

交通状态分析 | Python实现基于张量分解的交通流量时空模式挖掘

文章目录 效果一览文章概述研究内容源码设计参考资料效果一览 文章概述 交通状态分析 | Python实现基于张量分解的交通流量时空模式挖掘 研究内容 一般出行行程通常都由某种明确目的驱使,例如上班、购物或娱乐,出行的起始区域因其承担功能的不同,通常能够反映出用户的出行目…

【一、Linux文件与目录结构】

1 Linux 文件 Linux系统中一切皆文件 2 Linux目录结构 /bin Binary的缩写&#xff0c;存放着命令。 /sbin s即Super User&#xff0c;存放着root用户使用的系统管理程序。 /home 存放着普通用户的主目录&#xff0c;在Linux中每个用户都有一个自己的目录&#xff0c;一般…

近期学习论文总结 3(23.06.05-23.06.09)

公众号&#xff1a;EDPJ 目录 0. 摘要 1. Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization 1.1 主要思想 1.2 AdaIN 1.3 结构以及不同层使用 AdaIN 的效果 2. Watch your Up-Convolution: CNN Based Generative Deep Neural Networks are…

day46_项目

debug bug - 虫 第一台计算机,房子那么大,机械零件,齿轮,坏了,虫子(bug)卡着机器,debug(调试),虫子拿走了,机器就运行了,从此调试机器程序–>debug 目前: 这个卡机器的虫子,在博物馆 工具(IDEAEclipse)支持debug --> 追踪代码 如何使用debug 运行时候就得使用debug模式…

00后从事软件测试一年的心路历程

初识软件测试 不知不觉&#xff0c;我做软件测试已经快一年了&#xff0c;入职第一天的场景仿佛还在昨天。入职前&#xff0c;我对测试的认识仅仅停留在一些软件测试和测试方法的理论知识上&#xff0c;最多也是对自己的代码进行一些单元测试。 我之前所理解的测试是与开发分…

Django-可重用注册登录系统--项目搭建

文章目录 一、项目开始前的思考二、搭建项目环境三、设计数据库模型数据库模型文件设置数据库后端注册app生成迁移脚本并写入数据库测试是否成功数据库模型后台管理 路由与视图函数框架搭建路由配置视图函数的配置模板template的配置测试是否成功 前端界面设计与优化完善登录的…

【C/C++】函数参数默认值

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

【python+requests】接口自动化测试

这两天一直在找直接用python做接口自动化的方法&#xff0c;在网上也搜了一些博客参考&#xff0c;今天自己动手试了一下。 一、整体结构 上图是项目的目录结构&#xff0c;下面主要介绍下每个目录的作用。 Common:公共方法:主要放置公共的操作的类&#xff0c;比如数据库sql…