递归算法是把问题转化为规模缩小了的同类问题的子问题,然后递归调用函数(或过程)来表示问题的解。数学上常见的例子有阶乘,斐波那契数列等。那么今天我将为大家讲解下实际开发过程中会遇到的案例。我们在项目中一般处理树形结构的节点上下级关系中用到递归算法。
下面是一个递归的案例。
给你一组数据,根据ID和PID组织成树形结构。
给定树上任意几个节点,将这几个节点的所有下级 和 上级返回出来。
组织Node实例,建立为下面的树形结构。
1
|--11
| |--111
| |--1111
|--12
|--121
| |--1211
|--122
|--1221
给定节点 111,则返回数据有 1,11,111,1111
给定节点 121,则返回1,12,121,1211
给定节点 12,则返回1,12,121,1211,122,1221
给定节点 111 和 1211,则返回1,11,111,111,12,121,1211
备注:组织树性结构时,对于无效数据,找不到上级的节点,作为根来处理。
给定树上任意几个节点,将这几个节点的所有下级 和 上级返回出来。
组织Node实例,建立为下面的树形结构。
1
|--11
| |--111
| |--1111
|--12
|--121
| |--1211
|--122
|--1221
给定节点 111,则返回数据有 1,11,111,1111
给定节点 121,则返回1,12,121,1211
给定节点 12,则返回1,12,121,1211,122,1221
给定节点 111 和 1211,则返回1,11,111,111,12,121,1211
备注:组织树性结构时,对于无效数据,找不到上级的节点,作为根来处理。
- 首先,创建名称为Node的节点类,用来存放节点属性
import java.util.ArrayList; public class Node { public String ID = null; //节点id public String PID = null; //父节点id public Node(String ID1, String ID2) { this.ID = ID1; this.PID = ID2; } //定义上一节点变量 public Node upNode = null; //定义向下节点集合 public ArrayList<Node> subList = new ArrayList<Node>(); }
- 其次,创建名称为Test的处理类,用来进行递归实现题目运算
import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class Test { public static void main(String[] args) { //创建集合,建立题目中的树形结构 List<Node> list = new ArrayList<Node>(); list.add(new Node("1", "")); list.add(new Node("11", "1")); list.add(new Node("12", "1")); list.add(new Node("111", "11")); list.add(new Node("1111", "111")); list.add(new Node("121", "12")); list.add(new Node("122", "12")); list.add(new Node("1211", "121")); list.add(new Node("1221", "122")); //使用hashmap存放节点 HashMap<String, Node> nodeMap = new HashMap<String, Node>(); for (Node node : list) { //将ID对应的node放到HashMap中 nodeMap.put(node.ID, node); } //创建动态数组,用来处理顶级节点“1” List<Node> toplist = new ArrayList<Node>(); for (Node node : list) { if(node.PID != null && !"".equals(node.PID)) { Node upNode = nodeMap.get(node.PID); if(upNode != null) { // 添加下级 upNode.subList.add(node); // 设置上级 node.upNode = upNode; }else { toplist.add(node); } } else { toplist.add(node); } } // 给定节点 111,则返回数据有 1,11,111,1111 System.out.println(getNode("111", nodeMap)); // 给定节点 121,则返回1,12,121,1211 System.out.println(getNode("121", nodeMap)); // 给定节点 12,则返回1,12,121,1211,122,1221 System.out.println(getNode("12", nodeMap)); // 给定节点 111 和 1211,则返回1,11,111,111,12,121,1211 System.out.println(getNode("1211", nodeMap)); } private static String getNode(String id, HashMap<String, Node> nodeMap) { Node node = nodeMap.get(id); if(node == null) { return "Node不存在!"; } else { List<Node> resultList = new ArrayList<Node>(); getNodeUpNode(node, resultList); getNodeSubNode(node, resultList); boolean bFirst = true; StringBuffer sb = new StringBuffer(); for (Node t : resultList) { if(bFirst) { bFirst = false; } else { sb.append(","); } sb.append(t.ID); } return sb.toString(); } } //获取给定节点的上级节点 private static void getNodeUpNode(Node node, List<Node> resultList) { if(node.upNode != null) { //递归调用 getNodeUpNode(node.upNode, resultList); } resultList.add(node); } //获取给定节点的下级节点 private static void getNodeSubNode(Node node, List<Node> resultList) { for (Node subNode : node.subList) { //递归调用 resultList.add(subNode); getNodeSubNode(subNode, resultList); } } }
- 最后,运行即可输出如题结果