递归的应用递归生成树的排序吗

本文介绍了如何使用递归算法为树结构生成排序。通过测试类和特定的方法,从同级别节点中找到最大序列码,并根据父节点的orderCode和目标节点的order生成目标节点的orderCode。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 往mysql 插入数据虽然有先后顺序,但是取list的集合一般会 orderBy ,批量插入的 createTime or updateTime 都是 一样的,所以也不能根据这个排序,虽然可以根据汉字这些,但这里着重介绍

用递归的方式给  树生成排序吗

       // 生成排序吗 传入:list ;传出 list
        // 格式
        //  省 001 ,002
        //  市 001.001 ,001.002
        //  县 001.001.001 ,001.001.002

测试类:

@Test
    public void testList22() {


        // 构建数据
        List<Region> regionList= new ArrayList<>();
        Region  region1 = new Region(1,"山西省","0",null,"0");
        Region  region2 = new Region(2,"晋中市","0_1","0","0");
        Region  region3 = new Region(3,"平遥县","0_1_1","0_1","1");
        Region  region4 = new Region(4,"祁县","0_1_2","0_1","1");

        Region  region5 = new Region(2,"晋城市","0_2","0","1");


        Region  region6 = new Region(5,"北京市","1",null,"0");
        Region  region7 = new Region(6,"海淀区","1_1","1","0");
        Region  region8 = new Region(6,"朝阳区","1_2","1","1");
        Region  region9 = new Region(7,"创客小镇","1_1_1","1_1","1");



        // 生成排序吗 传入:list ;传出 list
        // 格式
        //  省 001 ,002
        //  市 001.001 ,001.002
        //  县 001.001.001 ,001.001.002
        regionList.add(region1);
        regionList.add(region2);
        regionList.add(region3);
        regionList.add(region4);
        regionList.add(region5);
        regionList.add(region6);
        regionList.add(region7);
        regionList.add(region8);
        regionList.add(region9);
        // 思路:拿到 每个 region的 children ,遍历 children ,用 父 的orderCode+ 兄弟的orderCode 码最大的值 + 1
         for (Region root : regionList){
             setRegionOrderCode(regionList  , null ,  root);
         }

        System.out.println(regionList);

    }
 public  List<Region> setRegionOrderCode(List<Region> sourceRegionList  ,Region fatherRegion , Region targetRegion){

        // 末级
        if ("1".equals(targetRegion.getIsEnd())) {
            // 递归的终止条件(很重要:节点的结束条件),返回 return 才会 进行下一个分支的循环
            return  new ArrayList<>();
        }

        // 非末级
        List<Region> childrenRegionList = sourceRegionList.stream()
                .filter(region ->( null != region.getParentCode() &&  region.getParentCode().equals(targetRegion.getCode())) )
                .collect(Collectors.toList());

        // 获取兄弟节点的orderCode(如果 兄弟节点 的 orderCode 都为null ,默认给个 "0")
        String brotherMaxOrderCode = getBrotherMaxOrderCode(sourceRegionList, targetRegion);
        // 设置 targetRegion 的 orderCode
        if (null == targetRegion.getParentCode()){
            // 兄弟节点 是 0 ,那么自身的 orderCode 为 0+1 =1
            targetRegion.setOrderCode(fullOrderCode("",String.valueOf(Integer.valueOf(brotherMaxOrderCode)+1)));
        }else{
            // orderCode  为 null 才会 set值,否则跳过
            if (null == targetRegion.getOrderCode() ||  "".equals(targetRegion.getOrderCode())) {
                targetRegion.setOrderCode(fullOrderCode(fatherRegion.getOrderCode(),String.valueOf(Integer.valueOf(brotherMaxOrderCode)+1)));
            }
        }

        for (Region children : childrenRegionList) {
            String brotherMaxOrderCode2 = getBrotherMaxOrderCode(sourceRegionList, children);
            // 设置 children 的orderCode
            children.setOrderCode(fullOrderCode(targetRegion.getOrderCode(),String.valueOf(Integer.valueOf(brotherMaxOrderCode2)+1)));
            //获取children ' children
            setRegionOrderCode(sourceRegionList  ,targetRegion, children);

        }

        return childrenRegionList;
    }

根据 targetRegion  从 同级别(brothers ) 中获取 已经 赋值 orderCode 的 brother 的最大 序列码

 public  String  getBrotherMaxOrderCode(List<Region> sourceRegionList ,Region targetRegion){
        List<Region>  brotherList =  getBrotherList(sourceRegionList,targetRegion);
        Region brother = new Region();
        if (!CollectionUtils.isEmpty(brotherList)) {
            brother =  brotherList.get(brotherList.size()-1);
        }
        if (null != brother.getOrderCode() &&  !"".equals(brother.getOrderCode())){
            // 截取字符串最后三位字符
            String lastThree = brother.getOrderCode().substring(brother.getOrderCode().length()-3);
            // 去掉 0 获取 String 类型 的 num
            String  brotherOrderCode = lastThree.replace("0","");
            System.out.println(Integer.valueOf(brotherOrderCode));
            return brotherOrderCode ;
        }else{
            // brothers 目前没有 orderCode 的值,那么就认为  brothers  的 orderCode 值为 "0"
            return "0";
        }
    }

根据  targetRegion 从 原数据获取 已经  有 orderCode 的 并且是同一个 parent的  brothers

 public  List<Region> getBrotherList(List<Region> sourceRegionList ,Region targetRegion){

        List<Region> fatherList = getFatherList(sourceRegionList, targetRegion);
        // 根目标处理
        if (null == targetRegion.getParentCode()) {
            List<Region>  brotherList =  sourceRegionList.stream()
                    .filter(region1 -> null == region1.getParentCode())
                    .filter(region2 ->( !targetRegion.getCode().equals(region2.getCode()) && !StringUtils.isEmpty(region2.getOrderCode())))
                    .sorted((r1,r2)->r1.getOrderCode().compareTo(r2.getOrderCode()))
                    .collect(Collectors.toList());
            return brotherList;
        }else{
            // 非根目标处理
            Region fatherRegion = fatherList.get(0);
            List<Region>  brotherList =  sourceRegionList.stream()
                    .filter(region1 -> (null != region1.getParentCode() && region1.getParentCode().equals(fatherRegion.getCode()) && !StringUtils.isEmpty(region1.getOrderCode())))
                    .filter(region2 -> !targetRegion.getCode().equals(region2.getCode()))
                    .sorted((r1,r2)->r1.getOrderCode().compareTo(r2.getOrderCode()))
                    .collect(Collectors.toList());
            return brotherList;
        }
    }

根据 targetRegion 获取 father的 方法:

   public  List<Region> getFatherList(List<Region> sourceRegionList ,Region targetRegion){
        List<Region>  fatherList =  sourceRegionList.stream()
                .filter(region ->(null != targetRegion.getParentCode() &&  targetRegion.getParentCode().equals(region.getCode())) )
                .collect(Collectors.toList());
        return fatherList;
    }

根据父orderCode 和 target 的 order 生成 target 自身的 orderCode 的工具类:

public String fullOrderCode(String parentOrderCode,String orderCode){
        String resultOrderCode = "";
        if (orderCode.length() == 1) {
            if ("".equals(parentOrderCode)) {
                resultOrderCode = "00"+orderCode;
            }else{
                resultOrderCode = parentOrderCode+".00"+orderCode;
            }
        }else if(orderCode.length() == 2){
            if ("".equals(parentOrderCode)) {
                resultOrderCode = "0"+orderCode;
            }else{
                resultOrderCode = parentOrderCode+".0"+orderCode;
            }
        }else if(orderCode.length() == 3){
            if ("".equals(parentOrderCode)) {
                resultOrderCode = orderCode;
            }else{
                resultOrderCode = parentOrderCode+"."+orderCode;
            }
        }
        return resultOrderCode;

    }

Region实体:

mport com.example.demo.entity.annotation.AttributeName;
import com.example.demo.entity.annotation.ValidAttribute;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @program: springboot_01
 * @description:
 * @author: guoyiguang
 * @create: 2021-01-14 14:43
 **/
public class Region {

    private Integer id;

    @AttributeName("区域名称")
    private String name;
    private String code;
    private String parentCode;


    private String orderCode;

    private String isEnd;

    public Region() {
    }

    public Region(Integer id, String name, String code, String parentCode, String isEnd) {
        this.id = id;
        this.name = name;
        this.code = code;
        this.parentCode = parentCode;
        this.isEnd = isEnd;
    }


    
 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值