• java 递归转非递归(树形转非树形)


    1.情景展示

    接着上一篇讲,在上一篇我们已经将数据通过递归转成了树形结构。

    如何将树形结构转非树形结构?(仍然按照树形层级关系进行平铺显示)

    如何将递归函数转成迭代函数?

    查看代码
    [{
    		name = 根节点,
    		childList = [{
    				name = 一级节点1,
    				childList = [{
    						name = 二级节点1.1,
    						childList = [],
    						id = 3,
    						parentId = 2
    					}, {
    						name = 二级节点1.2,
    						childList = [],
    						id = 4,
    						parentId = 2
    					}, {
    						name = 二级节点1.3,
    						childList = [],
    						id = 5,
    						parentId = 2
    					}
    				],
    				id = 2,
    				parentId = 1
    			}, {
    				name = 一级节点2,
    				childList = [{
    						name = 二级节点2.1,
    						childList = [{
    								name = 三级节点2.1.1,
    								childList = [],
    								id = 9,
    								parentId = 7
    							}, {
    								name = 三节点2.1.2,
    								childList = [],
    								id = 10,
    								parentId = 7
    							}
    						],
    						id = 7,
    						parentId = 6
    					}, {
    						name = 二级节点2.2,
    						childList = [],
    						id = 8,
    						parentId = 6
    					}
    				],
    				id = 6,
    				parentId = 1
    			}, {
    				name = 一级节点3,
    				childList = [{
    						name = 二级节点3.1,
    						childList = [{
    								name = 三级节点3.1.1,
    								childList = [{
    										name = 四级节点3.1.1.1,
    										childList = [{
    												name = 五级节点3.1.1.1.1,
    												childList = [],
    												id = 15,
    												parentId = 14
    											}
    										],
    										id = 14,
    										parentId = 13
    									}
    								],
    								id = 13,
    								parentId = 12
    							}
    						],
    						id = 12,
    						parentId = 11
    					}
    				],
    				id = 11,
    				parentId = 1
    			}
    		],
    		id = 1,
    		parentId = 0
    	}
    ]

    2.具体分析

    可以通过栈Stack来完成。

    3.解决方案

    代码实现

    /*
     * 将父节点下的子节点进行由嵌套改成平铺
     * @description: 递归转迭代
     * 按照层级关系,将嵌套改成平铺
     * @param: root 嵌套数据
     * @return: java.util.ArrayList<java.util.Map<java.lang.String,java.lang.Object>>
     * 平铺数据
     */
    public static ArrayList<Map<String, Object>> tileTraversal(Map<String, Object> root) {
        ArrayList<Map<String, Object>> res = new ArrayList<>();
        if (root == null) {
            return res;
        }
    
        // 建立一个新的栈实例
        Stack<Map<String, Object>> stack = new Stack<>();
        // 把原始内容压入新建栈
        stack.push(root);
        while (!stack.empty()) {
            // 出栈,将栈顶元素赋给temp
            Map<String, Object> temp = stack.pop();
            Map<String, Object> copyMap = new HashMap<>(temp.size());
            // 复制当前节点
            copyMap.putAll(temp);
            // 移除map(该节点)当中的子节点
            copyMap.remove("childList");
            // 将此节点放到集合当中
            res.add(copyMap);
    
            // 当前节点,存在子节点
            if (temp.get("childList") != null && ((List<Map<String, Object>>) temp.get("childList")).size() > 0) {
                // ((List<Map<String, Object>>) temp.get("childList")).forEach(m -> stack.push(m));
    
                List<Map<String, Object>> list = (List<Map<String, Object>>) temp.get("childList");
                for (int i = list.size() - 1; i >= 0; i--) {
                    // 将子节点倒序进栈
                    stack.push(list.get(i));
                }
            }
        }
        return res;
    }

    调用

    // mapList是树形结构(已经存在的数据)
    List<Map<String, Object>> tileList = new ArrayList<>();
    mapList.forEach(m -> tileList.addAll(tileTraversal(m)));
    System.out.println(tileList);
    [{name=根节点, id=1, parentId=0}, {name=一级节点1, id=2, parentId=1}, {name=二级节点1.1, id=3, parentId=2}, {name=二级节点1.2, id=4, parentId=2}, {name=二级节点1.3, id=5, parentId=2}, {name=一级节点2, id=6, parentId=1}, {name=二级节点2.1, id=7, parentId=6}, {name=三级节点2.1.1, id=9, parentId=7}, {name=三节点2.1.2, id=10, parentId=7}, {name=二级节点2.2, id=8, parentId=6}, {name=一级节点3, id=11, parentId=1}, {name=二级节点3.1, id=12, parentId=11}, {name=三级节点3.1.1, id=13, parentId=12}, {name=四级节点3.1.1.1, id=14, parentId=13}, {name=五级节点3.1.1.1.1, id=15, parentId=14}]

    4.效果展示

    转JSON

    System.out.println(JSON.toJSON(tileList));
    [{"name":"根节点","id":"1","parentId":"0"},{"name":"一级节点1","id":"2","parentId":"1"},{"name":"二级节点1.1","id":"3","parentId":"2"},{"name":"二级节点1.2","id":"4","parentId":"2"},{"name":"二级节点1.3","id":"5","parentId":"2"},{"name":"一级节点2","id":"6","parentId":"1"},{"name":"二级节点2.1","id":"7","parentId":"6"},{"name":"三级节点2.1.1","id":"9","parentId":"7"},{"name":"三节点2.1.2","id":"10","parentId":"7"},{"name":"二级节点2.2","id":"8","parentId":"6"},{"name":"一级节点3","id":"11","parentId":"1"},{"name":"二级节点3.1","id":"12","parentId":"11"},{"name":"三级节点3.1.1","id":"13","parentId":"12"},{"name":"四级节点3.1.1.1","id":"14","parentId":"13"},{"name":"五级节点3.1.1.1.1","id":"15","parentId":"14"}]

    格式化

    查看代码
    
    [{
    	"name": "根节点",
    	"id": "1",
    	"parentId": "0"
    },
    {
    	"name": "一级节点1",
    	"id": "2",
    	"parentId": "1"
    },
    {
    	"name": "二级节点1.1",
    	"id": "3",
    	"parentId": "2"
    },
    {
    	"name": "二级节点1.2",
    	"id": "4",
    	"parentId": "2"
    },
    {
    	"name": "二级节点1.3",
    	"id": "5",
    	"parentId": "2"
    },
    {
    	"name": "一级节点2",
    	"id": "6",
    	"parentId": "1"
    },
    {
    	"name": "二级节点2.1",
    	"id": "7",
    	"parentId": "6"
    },
    {
    	"name": "三级节点2.1.1",
    	"id": "9",
    	"parentId": "7"
    },
    {
    	"name": "三节点2.1.2",
    	"id": "10",
    	"parentId": "7"
    },
    {
    	"name": "二级节点2.2",
    	"id": "8",
    	"parentId": "6"
    },
    {
    	"name": "一级节点3",
    	"id": "11",
    	"parentId": "1"
    },
    {
    	"name": "二级节点3.1",
    	"id": "12",
    	"parentId": "11"
    },
    {
    	"name": "三级节点3.1.1",
    	"id": "13",
    	"parentId": "12"
    },
    {
    	"name": "四级节点3.1.1.1",
    	"id": "14",
    	"parentId": "13"
    },
    {
    	"name": "五级节点3.1.1.1.1",
    	"id": "15",
    	"parentId": "14"
    }]

    说明:

    事实上,使用SQL进行递归查询,返回的就是这种格式的数据,即:按照层级关系排好序展示出来;

    如果前端需要的是这种排好序的数据,直接返回即可;

    如果需要返回树形结构的话,见文末推荐。 

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

  • 相关阅读:
    GetForegroundWindow 与 GetActiveWindow 的区别 回复 "delphier" 的问题
    给 TStringGrid 添加鼠标拖动功能 回复 "dxx" 的问题
    Delphi 的编译指令(3): 常用的预定义条件标识符
    Delphi 的编译指令(1): $DEFINE、$UNDEF、$IFDEF、$ELSE、$ENDIF
    用多媒体库 Bass.dll 播放 mp3 [17] : 如何从内存流播放 回复 "小李子子" 的问题
    Delphi 的编译指令(4): 编译指令全表(未完)
    窗口跟随 回复 "heyongan" 的问题
    字符串转换到指定格式的宽字符 回复 "厨师" 的问题
    Dll 使用 PChar 参数的小例子 回复 "linximf" 的问题
    上周热点回顾(5.286.3)
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/16310118.html
Copyright © 2020-2023  润新知