如何在Java中创建动态树数据结构

时间:2016-09-02 17:33:41

标签: java tree parent

具体来说,我需要代表以下内容:

  1. 任何节点上的树都可以有任意数量的子项
  2. 每个父节点(在根之后)只是一个字符串(其子节点也是字符串)
  3. 我需要能够获取父项并列出所有子项(某种列表或字符串数​​组)给定表示给定节点的输入字符串
  4. 根据父级和子级之间的引用关系动态填充树结构。 给出的例子是我有一个member1赞助商另一个member2,member2赞助商成员3等等。已经有表记录关系
  5. 这是否有可用的结构?

    To build a tree like in the image

    我的数据来自数据库或列表,我将使用名称和关系循环显示信息,以确定节点是根,父还是子节点。

    因此,在循环中,我找到了一个孩子,我需要对父项的引用,以便在将子项添加到其父项之前,我可以将子项关系与父项进行比较。

    我找到的最接近的代码。

    public class TreeNode<T> implements Iterable<TreeNode<T>> {
    
        T data;
        TreeNode<T> parent;
        List<TreeNode<T>> children;
    
        public TreeNode(T data) {
            this.data = data;
            this.children = new LinkedList<TreeNode<T>>();
        }
    
        public TreeNode<T> addChild(T child) {
            TreeNode<T> childNode = new TreeNode<T>(child);
            childNode.parent = this;
            this.children.add(childNode);
            return childNode;
        }
    
        // other features ...
    
    }
    Sample usage:
    
    TreeNode<String> root = new TreeNode<String>("root");
    {
        TreeNode<String> node0 = root.addChild("node0");
        TreeNode<String> node1 = root.addChild("node1");
        TreeNode<String> node2 = root.addChild("node2");
        {
            TreeNode<String> node20 = node2.addChild(null);
            TreeNode<String> node21 = node2.addChild("node21");
            {
                TreeNode<String> node210 = node20.addChild("node210");
            }
        }
    }
    

    这是我到目前为止所做的。父母将被最新条目覆盖,因此我无法检索我之前添加的内容。

    public static TreeNode<String> getSet1() throws IOException {
    
            BufferedReader reader = new BufferedReader(new FileReader("test.txt"));
            String line;
    
            while ((line = reader.readLine()) != null) {
                String[] items = line.split(":");
    
                String name = items[0];
                String parent = items[1];
                String type = items[2];
    
                if (parent.equalsIgnoreCase("-") && type.equalsIgnoreCase("mainparent")) {
    
                    root = new TreeNode<String>(name);
    
    
                } else if (type.equalsIgnoreCase("ChildParent")  && parent.equalsIgnoreCase(root.toString())) {
    
                    childParent = root.addChild(name);
    
               } else if (type.equalsIgnoreCase("Child") && parent.equalsIgnoreCase(childParent.toString())) {
    
                    child = childParent.addChild(name);
                }
    
            }
    
            return root;
        }
    

1 个答案:

答案 0 :(得分:0)

您的图表显示任意深度的树,但您的代码仅处理祖父母 - &gt;父母 - &gt;子关系(在根处有一个祖父母)。

我会忽略这种类型,因为你需要的只是一个人的名字和他们父母的名字。如果父名称是短划线,则表示您拥有根。

现在对于每个人来说,你需要让父节点已经在树中(假设父母来到列表中的孩子之前 - 如果不是这样的话,那么问题会变得非常复杂,就像你想要的那样临时存放孤儿,并为每个新人查看他们是否是孤儿的父母。)

为了通过名称获取父级,您应该将已经处理的每个人存储在与树平行的第二个数据结构中。第二个数据结构应该可以很容易地按名称查找某人。地图,特别是Hashtables,非常适合这种情况。这是它的工作原理:

Map processedPersonsMap=new Hashtable<String, TreeNode<String>>();

对于每个人,您将它们存储在地图中,并按名称编制索引:

TreeNode<String> person=...;
processedPersonsMap.put(person.getData(), person);

当你读到一个新人并且他们的父母的名字不是破折号时,你会查找父母:

String parentName=items[1];
TreeNode<String> parent=processedPersonsMap.get(parentName);

通过这种方式,无论树有多深,你总能找到合适的父母。但是,请记住,这需要一个有效的输入文件,其中每个孩子都在其父级之后,并且不包含循环引用或缺少父级。

如果不满足这些条件,则必须明确处理它们。

相关问题