使用递归删除树形结构的所有子节点(java和mysql实现)

1.业务场景

有如下树形结构:
+—0
+—1
+—2
+—4
+—5
+—3

如果删除某个父节点,则其子节点,以及其子节点的子节点,以此类推,需要全部删除。

2.Java实现

使用Map存储树形结构的数据,id为map的key,pid为树形结构的value。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

public class TreeNodes {
  public static void main(String[] args) {
    test();
  }

  //测试removeSons方法
  public static void test(){

    //原始的Map
    Map<Integer, Integer> t=new HashMap<Integer, Integer>();
    //  ID PID
    t.put(1, 0);
    t.put(2, 1);
    t.put(3, 1);
    t.put(4, 2);
    t.put(5, 4);
    System.out.println("—— —— —— —— —— ——原始的Map —— —— —— —— —— —— ——");

    Set<Integer> keys=t.keySet();
    Iterator<Integer> iterator=keys.iterator();
    System.out.println("ID —— PID");
    while(iterator.hasNext()){
      Integer i=iterator.next();
      System.out.println(i+" —— "+t.get(i));
    }

    int k=2;
    //递归删除k的所有子节点
    System.out.println("—— —— —— —— —— ——删除掉的节点 —— —— —— —— —— —— ——");
    removeTreeNodes(t,k);
    //删除k节点本身
    t.remove(k);
    System.out.println();
    System.out.println("—— —— —— —— —— —— 递归删除["+k+"]的所有子节点后的Map —— —— ");

    iterator=keys.iterator();
    System.out.println("ID —— PID");
    while(iterator.hasNext()){
      Integer i=iterator.next();
      System.out.println(i+" —— "+t.get(i));
    }
  }

  //递归删除所有的子节点
  public static Map<Integer, Integer> removeTreeNodes(Map<Integer, Integer> t,Integer k){
    //所有需要删除的子节点
    List<Integer> sons=new ArrayList<Integer>();
    sons.add(k);
    List<Integer> temp=new ArrayList<Integer>();
    //循环递归删除,所有以k为父节点的节点
    while(true){
      for(Integer s:sons){
        Set<Integer> keys=t.keySet();
        Iterator<Integer> it=keys.iterator();
        while(it.hasNext()){
          Integer n=it.next();
          //如果父节点(即Map的value)为需要删除的节点,则记录此节点,并在Map中删除
          if(t.get(n)==s){
            temp.add(n);
            it.remove();
            System.out.println("删除了ID=["+n+"]的节点,其父节点为["+s+"]");
          }
        }
      }

      //如果此节点包含子节点,则将子节点赋值给sons;否则表示所有子节点已经删除,结束循环
      if(temp.size()>0){
        sons=temp;
        temp=new CopyOnWriteArrayList<Integer>();
      }else{
        break;
      }
    }

    return t;
  }
}

3.SQL实现

利用存储过程,将所有子节点存储到临时表里。

存储过程执行完后会产生一个临时表,id为需要删除的子节点id,nLevel 为节点深度,sCort 为排序字段。

建表并插入数据:

CREATE TABLE treeNodes
(
 id INT PRIMARY KEY,
 pid INT
);
INSERT INTO treeNodes VALUES
(1, 0),
(2, 1),
(3, 1),
(4, 2),
(5, 4);

创建并调用存储过程:

DELIMITER//

DROP PROCEDURE IF EXISTS removeTreeNodes//

CREATE PROCEDURE removeTreeNodes(IN rootid INT)
 BEGIN
 DECLARE LEVEL INT ;
 DROP TABLE IF EXISTS tempNodes;
 CREATE TABLE tempNodes (
  id INT,
  nLevel INT,
  sCort VARCHAR(8000)
 );
 SET LEVEL=0 ;
 INSERT INTO tempNodes SELECT id,LEVEL,ID FROM treeNodes WHERE PID=rootid;
 WHILE ROW_COUNT()>0 DO
  SET LEVEL=LEVEL+1 ;
  INSERT INTO tempNodes
  SELECT A.ID,LEVEL,CONCAT(B.sCort,A.ID) FROM treeNodes A,tempNodes B
  WHERE A.PID=B.ID AND B.nLevel=LEVEL-1 ;
 END WHILE;
 END;
//
DELIMITER ;

CALL removeTreeNodes(0);

下面是需要删除的子节点:

SELECT CONCAT(SPACE(B.nLevel*2),'+--',A.id)
FROM treeNodes A,tempNodes B
WHERE A.ID=B.ID
ORDER BY B.sCort;

以上这篇使用递归删除树形结构的所有子节点(java和mysql实现)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java递归遍历树形结构

    废话不多说了,直接给大家贴代码,具体代码如下所示: //菜单树形结构 public JSONArray treeMenuList(JSONArray menuList, int parentId) { JSONArray childMenu = new JSONArray(); for (Object object : menuList) { JSONObject jsonMenu = JSONObject.fromObject(object); int menuId = jsonMenu.ge

  • MySQL实现树状所有子节点查询的方法

    本文实例讲述了MySQL实现树状所有子节点查询的方法.分享给大家供大家参考,具体如下: 在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点.但很遗憾,在MySQL的目前版本中还没有对应的功能. 在MySQL中如果是有限的层次,比如我们事先如果可以确定这个树的最大深度是4, 那么所有节点为根的树的深度均不会超过4,则我们可以直接通过left join 来实现. 但很多时候我们无法控制树的深度.这时就需要

  • MySQL递归查询树状表的子节点、父节点具体实现

    简介:mysql5.0.94版本,该版本以及较高级的版本(5.5.6等等)尚未支持循环递归查询,和sqlserver.oracle相比,mysql难于在树状表中层层遍历的子节点.本程序重点参考了下面的资料,写了两个sql存储过程,子节点查询算是照搬了,父节点查询是逆思维弄的. 表结构和表数据就不公示了,查询的表user_role,主键是id,每条记录有parentid字段(对应该记录的父节点,当然,一个父节点自然会有一个以上的子节点嘛) 复制代码 代码如下: CREATE FUNCTION `g

  • 使用递归删除树形结构的所有子节点(java和mysql实现)

    1.业务场景 有如下树形结构: +-0 +-1 +-2 +-4 +-5 +-3 如果删除某个父节点,则其子节点,以及其子节点的子节点,以此类推,需要全部删除. 2.Java实现 使用Map存储树形结构的数据,id为map的key,pid为树形结构的value. import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.uti

  • 详解Java递归实现树形结构的两种方式

    目录 0.引言 1.数据准备 2.类型转化 3.递归实现方法 3.1.Java7及以下纯Java递归实现 3.2.Java8及以上借助lamda表达式实现 0.引言 在开发的过程中,很多业务场景需要一个树形结构的结果集进行前端展示,也可以理解为是一个无限父子结构,常见的有报表指标结构.菜单结构等.Java中递归实现树形结构的两种常见方式如下: Java7及以下纯Java递归实现 Java8及以上借助lamda表达式实现 1.数据准备 Java实体类NodePO对应数据库表 package com

  • MySQL递归查找树形结构(这个方法太实用了!)

    目录 1.数据库中的树形结构 2.MySQL中如何查找相应的数据 3.准备工作 4.具体的实现(由浅入深) 总结 这两天,遇到了重要节点的需求.这里简单做个总结. 1.数据库中的树形结构 数据库中存贮的数据,以ID和P_ID(父id),来存贮树形结构 这样如果需要查找某个节点的子节点,就可以寻找P_ID.如果要查找所有子节点,就需要遍历所有的子节点的子节点. 如果要判断是否为同级的节点,就可以查找是否有相同的节点. 2.MySQL中如何查找相应的数据 这里,我采用的是一个存储函数.在查询时可以直

  • Java递归遍历树形结构的实现代码

    废话不多说了,直接给大家贴代码,具体代码如下所示: //菜单树形结构 public JSONArray treeMenuList(JSONArray menuList, int parentId) { JSONArray childMenu = new JSONArray(); for (Object object : menuList) { JSONObject jsonMenu = JSONObject.fromObject(object); int menuId = jsonMenu.ge

  • Java异常继承结构解析_动力节点Java学院整理

    Java异常类层次结构图: 异常的英文单词是exception,字面翻译就是"意外.例外"的意思,也就是非正常情况.事实上,异常本质上是程序上的错误,包括程序逻辑错误和系统错误.比如使用空的引用.数组下标越界.内存溢出错误等,这些都是意外的情况,背离我们程序本身的意图.错误在我们编写程序的过程中会经常发生,包括编译期间和运行期间的错误,在编译期间出现的错误有编译器帮助我们一起修正,然而运行期间的错误便不是编译器力所能及了,并且运行期间的错误往往是难以预料的.假若程序在运行期间出现了错误

  • tomcat目录结构简介_动力节点Java学院整理

    tomcat目录结构简介 如果我们有一个web应用,名称为"mail"(同时也是web应用所在目录的名称),那么其目录内不同类型的文件应该服从如下放置的规则: 一般来讲: 对于html.jsp.css.js文件等,可以直接放置在web应用所在目录中,当然如果某些文件比较多,可以另外创建一些目录来存放. 而对于除了上述几种文件外,一些不希望被外界能访问到的文件必须放在[WEB-INF]目录中,文件名不许更改,纯大写,一点不能有区别,否则必定出错,而在这个目录下会存放一些我们开发所需的Ja

  • java之TreeUtils生成一切对象树形结构案例

    项目中经常会遇到各种需要以树形结构展示的功能,比较常见的,如菜单树,分类树,部门树等等,如果为每种类型都遍历递归生成树形结构返回给前端,显得有些冗余且麻烦,并且其实逻辑都是一致的,只是遍历的对象不同而已,故其实可以通过面向接口思维,来实现这种通用工具类的实现. TreeNode用来表示每个树节点的抽象,即需要生成树的对象需要实现此接口. /** * 树节点父类,所有需要使用{@linkplain TreeUtils}工具类形成树形结构等操作的节点都需要实现该接口 * * @param <T>

  • JS前端二维数组生成树形结构示例详解

    目录 问题描述 实现步骤 完整代码 问题描述 前端在构建国家的省市区结构时,接口返回的不是树形结构,这个时候就需要我们进行转化.以下数据为例 [ [ { "districtId": 1586533852834, "parentCode": "000", "nodeCode": "000001", "name": "浙江省", "districtType&qu

  • JAVA递归生成树形菜单的实现过程

    递归生成一个如图的菜单,编写两个类数据模型Menu.和创建树形的MenuTree.通过以下过程实现: 1.首先从菜单数据中获取所有根节点. 2.为根节点建立次级子树并拼接上. 3.递归为子节点建立次级子树并接上,直至为末端节点拼接上空的“树”. 首先,编写数据模型Menu.每条菜单有自己的id.父节点parentId.菜单名称text.菜单还拥有次级菜单children. import java.util.List; public class Menu { private String id;

随机推荐