一、引言
公司新入职员工对列表转树的方法不了解,和他沟通了算法还是不明白的样子,网上找了几个类似的例子都不是很满意,只好自己动手写了一个,有需要的童鞋自取。
二、解决思路
主要的算法:
1、找出所有的根节点;(没有上级节点或列表中找不到父节点的节点都作为根基点处理)
2、找出每个根节点下的各级子节点;
3、打印输出最后的树形结构;
三、源代码
package com.duoduo.demo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 列表转树
* @author [email protected]
* @date 2018年10月15日 上午11:22:41
*/
public class ListToTreeTest {
public static void main(String[] args) {
List<TreeNode<Integer>> nodes = new ArrayList<TreeNode<Integer>>(0);
nodes.add(new TreeNode<Integer>(1, "TreeNode 1", 0));
nodes.add(new TreeNode<Integer>(2, "TreeNode 2", 1));
nodes.add(new TreeNode<Integer>(3, "TreeNode 3", 1));
nodes.add(new TreeNode<Integer>(4, "TreeNode 4", 2));
nodes.add(new TreeNode<Integer>(5, "TreeNode 5", 3));
nodes.add(new TreeNode<Integer>(6, "TreeNode 6", 3));
nodes.add(new TreeNode<Integer>(7, "TreeNode 7", 0));
nodes.add(new TreeNode<Integer>(8, "TreeNode 8", 7));
nodes.add(new TreeNode<Integer>(9, "TreeNode 9", 7));
nodes.add(new TreeNode<Integer>(10, "TreeNode 10", 8));
nodes.add(new TreeNode<Integer>(11, "TreeNode 11", 9));
nodes.add(new TreeNode<Integer>(12, "TreeNode 12", 10));
List<TreeNode<Integer>> roots = findRoots(nodes);
for (TreeNode<Integer> root : roots) {
root.setChildren(findChildren(root.getId(), nodes));
}
for (TreeNode<Integer> root : roots) {
printTree(root, "----");
}
}
private static List<TreeNode<Integer>> findRoots(List<TreeNode<Integer>> nodes) {
Map<Integer, Integer> map = new HashMap<Integer, Integer>(0);
List<TreeNode<Integer>> result = new ArrayList<TreeNode<Integer>>(0);
for (TreeNode<Integer> node : nodes) {
map.put(node.getId(), 1);
}
for (TreeNode<Integer> node : nodes) {
if (node.getParentId() == null || !map.containsKey(node.getParentId())) {
result.add(node);
}
}
return result;
}
private static List<TreeNode<Integer>> findChildren(Integer parentId, List<TreeNode<Integer>> nodes) {
List<TreeNode<Integer>> result = new ArrayList<TreeNode<Integer>>(0);
for (TreeNode<Integer> node : nodes) {
if (node.getParentId() == parentId) {
node.setChildren(findChildren(node.getId(), nodes));
result.add(node);
}
}
return result;
}
private static void printTree(TreeNode<Integer> node, String prefix) {
System.out.println(prefix + node.getName());
List<TreeNode<Integer>> children = node.getChildren();
if (children != null && !children.isEmpty()) {
for (TreeNode<Integer> child : children) {
printTree(child, prefix + "----");
}
}
}
}
class TreeNode<T> {
private T id;
private String name;
private T parentId;
private List<TreeNode<T>> children;
public TreeNode() {
}
/**
* @param id
* @param name
* @param parentId
*/
public TreeNode(T id, String name, T parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
/**
* @return the id
*/
public T getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(T id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the parentId
*/
public T getParentId() {
return parentId;
}
/**
* @param parentId the parentId to set
*/
public void setParentId(T parentId) {
this.parentId = parentId;
}
/**
* @return the children
*/
public List<TreeNode<T>> getChildren() {
return children;
}
/**
* @param childrens the children to set
*/
public void setChildren(List<TreeNode<T>> children) {
this.children = children;
}
}
四、测试结果
控制台输出结果如下所示,与预期结果一致,算法正确。
----TreeNode 1
--------TreeNode 2
------------TreeNode 4
--------TreeNode 3
------------TreeNode 5
------------TreeNode 6
----TreeNode 7
--------TreeNode 8
------------TreeNode 10
----------------TreeNode 12
--------TreeNode 9
------------TreeNode 11