当前位置: 移动技术网 > IT编程>开发语言>Java > 使用递归删除树形结构的所有子节点(java和mysql实现)

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

2019年07月19日  | 移动技术网IT编程  | 我要评论

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实现)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网