java中树视图的扁平组织结构

java中树视图的扁平组织结构,java,data-structures,Java,Data Structures,我的组织结构如下所示- T1 |'''' ''''| T2 T3 | T4 在数据库中存储为- +----+---------+-----------+-----------+ | ID | TEAM_ID | PARENT_ID | TEAM_NAME | +----+---------+-----------+-----------+ | 1 | 1 | 1 | T1 | | 2 | 2 |

我的组织结构如下所示-

      T1
|''''   ''''|
T2          T3
|
T4
在数据库中存储为-

+----+---------+-----------+-----------+
| ID | TEAM_ID | PARENT_ID | TEAM_NAME |
+----+---------+-----------+-----------+
|  1 |       1 |         1 | T1        |
|  2 |       2 |         2 | T2        |
|  3 |       2 |         1 | T2        |
|  4 |       3 |         1 | T3        |
|  5 |       3 |         3 | T3        |
|  6 |       4 |         4 | T4        |
|  7 |       4 |         2 | T4        |
|  8 |       4 |         1 | T4        |
+----+---------+-----------+-----------+
我想从上表给出的平面数据重新构建上面的树

我目前的做法是-

Map<Long, List<TeamHierarchy>> tree = new HashMap<>();
        for (TeamHierarchy n : flatTeamStructure) {
            if (n.getParentTeamId() == n.getTeamId()) {
                if (!tree.containsKey(n.getParentTeamId())) {
                    tree.put(n.getParentTeamId(), new ArrayList<TeamHierarchy>());
                }
            } else {
                if (!tree.containsKey(n.getParentTeamId())) {
                    tree.put(n.getParentTeamId(), new ArrayList<TeamHierarchy>());
                }
                tree.get(n.getParentTeamId()).add(n);
            }
        }
Map tree=newhashmap();
对于(团队层次结构n:flatTeamStructure){
如果(n.getParentTeamId()==n.getTeamId()){
如果(!tree.containsKey(n.getParentTeamId())){
put(n.getParentTeamId(),newArrayList());
}
}否则{
如果(!tree.containsKey(n.getParentTeamId())){
put(n.getParentTeamId(),newArrayList());
}
get(n.getParentTeamId()).add(n);
}
}
这并不完全正确,因为我在T1的孩子身上也得到了T4。
我只想要一个直接的孩子。任何没有递归的建议都会有帮助

我不确定这是最有效的方法,但它应该有效。我会尝试将每个团队Id映射到其正确的家长。这里的困难是您的表包含冗余信息,因此您必须能够将其删除

这个想法是从根开始构建树,如果在树的更深处找到更好的父级,则递归地修改父级。这里有一个简单的独立程序示例,应该可以帮助您继续

public class TestTree {
    private static List<Entry> entries = new ArrayList<Entry>();

    public static void main(String[] args) throws Exception {
        // simulate the DB entries
        entries.add(new Entry(1, 1, 1, "T1"));
        entries.add(new Entry(2, 2, 2, "T2"));
        entries.add(new Entry(3, 2, 1, "T2"));
        entries.add(new Entry(4, 3, 1, "T3"));
        entries.add(new Entry(5, 3, 3, "T3"));
        entries.add(new Entry(6, 4, 4, "T4"));
        entries.add(new Entry(7, 4, 2, "T4"));
        entries.add(new Entry(8, 4, 1, "T4"));

        // the root is the one entry with no parent other than self
        int root = 1;

        // map all relationships to the root
        Map<Integer, Integer> tree = new HashMap<Integer, Integer>();   // ID -> parent ID
        buildTree(tree, root);

        System.out.println(tree);

        // From this Map, it should be pretty obvious how to build the tree.
    }

    private static void buildTree(Map<Integer, Integer> tree, int parentId) {
        boolean dirty = false;
        for(Entry entry : entries) {
            if(entry.parentId == parentId && entry.teamId != parentId) {
                tree.put(entry.teamId, parentId);
                dirty = true;
            }
        }

        if(dirty) {
            // Continue building the tree from each node that was updated
            for(Integer nodeId : tree.keySet()) {
                if(tree.get(nodeId) == parentId) buildTree(tree, nodeId);
            }
        }
    }

    private static class Entry {
        int id;
        int teamId;
        int parentId;
        String teamName;

        Entry(int id, int teamId, int parentId, String teamName) {
            this.id = id;
            this.teamId = teamId;
            this.parentId = parentId;
            this.teamName = teamName;
        }
    }
公共类测试树{
私有静态列表项=新的ArrayList();
公共静态void main(字符串[]args)引发异常{
//模拟数据库条目
增加(新条目(1,1,1,“T1”);
增加(新条目(2,2,2,“T2”);
增加(新条目(3,2,1,“T2”);
增加(新条目(4,3,1,“T3”);
增加(新条目(5,3,3,“T3”);
增加(新的分录(6,4,4,“T4”);
增加(新的分录(7,4,2,“T4”);
增加(新的分录(8,4,1,“T4”);
//根是除self之外没有父项的条目
int root=1;
//将所有关系映射到根
映射树=新建HashMap();//ID->父ID
构建树(树,根);
System.out.println(树);
//从这张地图上看,应该很清楚如何构建这棵树。
}
私有静态void构建树(映射树,int-parentId){
布尔脏=假;
对于(条目:条目){
if(entry.parentId==parentId&&entry.teamId!=parentId){
tree.put(entry.teamId、parentId);
肮脏=真实;
}
}
如果(脏的){
//继续从更新的每个节点构建树
for(整数nodeId:tree.keySet()){
if(tree.get(nodeId)=parentId)buildTree(tree,nodeId);
}
}
}
私有静态类条目{
int-id;
int团队ID;
int-parentId;
字符串组名;
条目(int-id、int-teamId、int-parentId、String-teamName){
this.id=id;
this.teamId=teamId;
this.parentId=parentId;
this.teamName=团队名称;
}
}
更新

对于递归方法厌恶者(如果您认为树太深,以至于方法调用堆栈崩溃):

import java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Stack;
公共类测试树{
私有静态列表项=新的ArrayList();
公共静态void main(字符串[]args)引发异常{
//模拟数据库条目
增加(新条目(1,1,1,“T1”);
增加(新条目(2,2,2,“T2”);
增加(新条目(3,2,1,“T2”);
增加(新条目(4,3,1,“T3”);
增加(新条目(5,3,3,“T3”);
增加(新的分录(6,4,4,“T4”);
增加(新的分录(7,4,2,“T4”);
增加(新的分录(8,4,1,“T4”);
//根是除self之外没有父项的条目
int root=1;
//将所有关系映射到根
映射树=新建HashMap();//ID->父ID
堆栈=新堆栈();
栈.推(根);
做{
int parentId=stack.pop();
if(构建树(树,父ID)){
//继续从更新的每个节点构建树
for(整数nodeId:tree.keySet()){
if(tree.get(nodeId)=parentId)stack.push(nodeId);
}
}
}而(!stack.isEmpty());
System.out.println(树);
//从这张地图上看,应该很清楚如何构建这棵树。
}
私有静态布尔构建树(映射树,int-parentId){
布尔脏=假;
对于(条目:条目){
if(entry.parentId==parentId&&entry.teamId!=parentId){
tree.put(entry.teamId、parentId);
肮脏=真实;
}
}
返脏;
}
私有静态类条目{
int-id;
int团队ID;
int-parentId;
字符串组名;
条目(int-id、int-teamId、int-parentId、String-teamName){
this.id=id;
this.teamId=teamId;
this.parentId=parentId;
this.teamName=团队名称;
}
}
}

上表中的扁平团队结构是否足以构建一个结构良好的树?例如,以T4为例,它的父项ID为4、2、1,哪一个是直接父项?您如何判断?@svasa这是一个问题。我们可以确定,但它需要递归。然后是O(N^2)抱歉,我没有注意到您对非递归方法的请求。我编辑了响应并保留了两个版本。它们实际上是相同的,只是在非递归版本中,您必须跟踪自己的堆栈。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

public class TestTree {
    private static List<Entry> entries = new ArrayList<Entry>();

    public static void main(String[] args) throws Exception {
        // simulate the DB entries
        entries.add(new Entry(1, 1, 1, "T1"));
        entries.add(new Entry(2, 2, 2, "T2"));
        entries.add(new Entry(3, 2, 1, "T2"));
        entries.add(new Entry(4, 3, 1, "T3"));
        entries.add(new Entry(5, 3, 3, "T3"));
        entries.add(new Entry(6, 4, 4, "T4"));
        entries.add(new Entry(7, 4, 2, "T4"));
        entries.add(new Entry(8, 4, 1, "T4"));

        // the root is the one entry with no parent other than self
        int root = 1;

        // map all relationships to the root
        Map<Integer, Integer> tree = new HashMap<Integer, Integer>();   //    ID -> parent ID
        Stack<Integer> stack = new Stack<Integer>();

        stack.push(root);
        do {
            int parentId = stack.pop();

            if(buildTree(tree, parentId)) {
                // Continue building the tree from each node that was updated
                for(Integer nodeId : tree.keySet()) {
                    if(tree.get(nodeId) == parentId) stack.push(nodeId);
                }
            }
        } while(!stack.isEmpty());

        System.out.println(tree);

        // From this Map, it should be pretty obvious how to build the tree.
    }

    private static boolean buildTree(Map<Integer, Integer> tree, int parentId) {
        boolean dirty = false;
        for(Entry entry : entries) {
            if(entry.parentId == parentId && entry.teamId != parentId) {
                tree.put(entry.teamId, parentId);
                dirty = true;
            }
        }

        return dirty;
    }

    private static class Entry {
        int id;
        int teamId;
        int parentId;
        String teamName;

        Entry(int id, int teamId, int parentId, String teamName) {
            this.id = id;
            this.teamId = teamId;
            this.parentId = parentId;
            this.teamName = teamName;
        }
    }
}