递归算法升级

算法

1.递归算法

1.1计算n以内的和

//n以内的和
    public static Integer sum(Integer num){
        if(num <0){
            return 0;
        }
        return num+sum(num-1);
    }

1.2计算n的阶乘

//n以内的阶乘
    public static Integer multiply(Integer num){
        if(num <=0){
            return 1;
        }
        return num*multiply(num-1);
    }

1.3计算斐波那契数列的第n项

//计算斐波那契数列的第n项
    public static Integer shuLie(Integer num){
        /**
         * 第n项为第n-1项与n-2项的和
         * ···
         * 第3项为第2项的与第1项的和
         * 第2项为1,第1项为1
         */
        if(num ==0 ){
            return 0;
        };
        if(num ==1){
            return 1;
        }
        return shuLie(num-1)+shuLie(num-2);
    }

1.4遍历文件

File file = new File("/3");
file(file);

//遍历查询文件
public static void file(File pfile){
    File[] files = pfile.listFiles();
    for (File file : files) {
        if(file.isDirectory()){
            file(file);
        }else{
            if(file.getName().endsWith(".md")){
                System.out.println("文件的AbsolutePath为:"+file.getAbsolutePath());
                System.out.println("文件的Path为:"+file.getPath());
            }
        }
    }
}
文件的AbsolutePath为:F:\3\MD\autoconfig.md //绝对路径
文件的Path为:\3\MD\autoconfig.md //相对于传过来的相对路径'/3'下的路径地址

2升级

实体类:

@Data
public class Demo {
    private int id;
    private int pid;
    private String name;
    private List children;
}

数据库数据:
数据
结果:

[
    {
        "id":1,
        "pid":0,
        "name":"一级节点",
        "children":[
            {
                "id":2,
                "pid":1,
                "name":"二级节点",
                "children":[
                    {
                        "id":4,
                        "pid":2,
                        "name":"三级节点",
                        "children":null
                    }
                ]
            },
            {
                "id":3,
                "pid":1,
                "name":"二级节点",
                "children":null
            }
        ]
    },
    {
        "id":5,
        "pid":0,
        "name":"一级节点",
        "children":null
    }
]

2.1解法一

参考文章

/**
 * 递归封装树形菜单
 */
public class Tree {
    List<Demo> nodes = new ArrayList<Demo>();

    public Tree(List<Demo> nodes) {
        super();
        this.nodes = nodes;
    }

    /**
     * 构建树形结构
     *
     * @return
     */
    public List<Demo> buildTree() {
        List<Demo> Demos = new ArrayList<Demo>();
        List<Demo> rootNodes = getRootNodes(); //创建一级节点
        for (Demo rootNode : rootNodes) {
            buildChildNodes(rootNode);
            Demos.add(rootNode);
        }
        return Demos;
    }

    /**
     * 递归子节点
     *
     * @param node
     */
    public void buildChildNodes(Demo node) { //node为一级节点
        List<Demo> children = getChildNodes(node); //获取一级节点下所有的子节点
        if (!children.isEmpty()) {
            for (Demo child : children) {
                buildChildNodes(child);
            }
            node.setChildren(children);
        }
    }

    /**
     * 获取父节点下所有的子节点
     *
     * @param pnode
     * @return
     */
    public List<Demo> getChildNodes(Demo pnode) {
        List<Demo> childNodes = new ArrayList<Demo>();
        for (Demo n : nodes) {
            if (pnode.getId() == n.getPid()) {
                childNodes.add(n);
            }
        }
        return childNodes;
    }

    /**
     * 判断是否为根节点
     * 查询所有父节点为0的节点
     * @return
     */
    public boolean rootNode(Demo node) {
        boolean isRootNode = true;
        for (Demo n : nodes) {
            if (node.getPid() == (n.getId())) {
                isRootNode = false;
                break;
            }
        }
        return isRootNode;
    }

    /**
     * 获取集合中所有的根节点
     *
     * @return
     */
    public List<Demo> getRootNodes() {
        List<Demo> rootNodes = new ArrayList<Demo>();
        for (Demo n : nodes) {
            if (rootNode(n)) { //根节点为false
                rootNodes.add(n);
            }
        }
        return rootNodes;
    }
}

2.2解法二

/**
 * 递归封装树形菜单
 */
public class Tree2 {

    List<Demo> nodes = new ArrayList<Demo>();

    public Tree2(List<Demo> nodes) {
        super();
        this.nodes = nodes;
    }


    public List<Demo> getlist() {
        List<Demo> mapTree = new ArrayList<>();
        for (Demo Demo : nodes) {
            if(Demo.getPid() == 0){
                mapTree.add(createTreeChildren(Demo,nodes));
            }
        }
        return mapTree;
    }

    private Demo createTreeChildren(Demo Demo, List<Demo> nodes) {

        for (Demo Demo1 : nodes) {
            if (String.valueOf(Demo1.getPid()).equals(String.valueOf(Demo.getId())) ) {
                if (Demo.getChildren() == null) {
                    Demo.setChildren(new ArrayList<>());
                }
                Demo.getChildren().add(createTreeChildren(Demo1, nodes));
            }
        }
        return Demo;
    }
}

以两种方法都是拿来即用,修改参数即可不用改太多东西

2.3解法三

    @Override
    public Area generatorTree(){
        List<Area> areas = areaDao.selectAll();
        // 获取顶级的对象,只是查询一个省,要是查询多个要返回list
        Area area = get(0l);
        Map<Long,List<Area>> pidmap = getpidmap(areas);
        Area trees = getTreeList(area,pidmap);
        return trees;
    }
    public Area getTreeList(Area area,Map<Long,List<Area>> pidmap){
        Long id = area.getId();
        //只获取下一级的地区信息,避免了全部的循环
        List<Area> areas1 = pidmap.get(id);
        if(areas1 != null){
            for (Area area1 : areas1) {
                area.getKids().add(getTreeList(area1,pidmap));
            }
        }
        return area;
    }
    
    //组装数据,key为pid,值为pid下的一级地区
    public Map<Long,List<Area>> getpidmap(List<Area> areas){
        Map<Long,List<Area>> map = new LinkedHashMap<>();
        areas.forEach(item -> {
            Long pid = item.getPid();
            List<Area> areas1 = map.get(pid);
            if(areas1 == null){
                areas1 = new LinkedList<>();
                areas1.add(item);
            }else {
                areas1.add(item);
            }
            map.put(pid,areas1);
        });
        return map;
    }

解法三节省了全部循环的操作,增加了组装数据的操作,解法二循环了全部。相比之下,解法三更快一点,因为不需要每一次都要循环全部的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值