获取树中Node的父路径

时间:2018-11-06 13:02:54

标签: java

我正在使用以下代码转换如下的平面结构:

test/test2/test3
test/test5/test2
test/test7/test5/test4
test/test7/test5/test9

变成一棵像这样的树

        test
|        |      |
test2   test5   test7
|        |      |
test3   test2   test5
                |        |
                test4    test9

代码:

import java.util.*;
class Tree
{
    class Node
    {
        String data;
        ArrayList<Node> children;

        public Node(String data)
        {
            this.data = data;
            children = new ArrayList<Node>();
        }

        public ArrayList<Node> getChildren()
        {
            return children;
        }

        public Node getChild(String data)
        {
            for(Node n : children)
                if(n.data.equals(data))
                    return n;

            return null;
        }
    }

    private Node root;

    public Tree()
    {
        root = new Node("");
    }

    public boolean isEmpty()
    {
        return root==null;
    }

    public void add(String str)
    {
        Node current = root;
        StringTokenizer s = new StringTokenizer(str, "/");
        while(s.hasMoreElements())
        {
            str = (String)s.nextElement();
            Node child = current.getChild(str);
            if(child==null)
            {
                current.children.add(new Node(str));
                child = current.getChild(str);
            }
            current = child;
        }
    }

    public void get()
    {
        return root;
    }
}

我使用“添加”功能将上述平坦路径拆分为一棵树,并且效果很好,并且能够向前导航。虽然,我希望能够导航到具有给定路径的Node,而且当我导航到某个Node时,我希望能够将其跟踪到根元素。例如,如果我从test-> test2-> test3导航,我想从根目录获取路径,例如test / test2 / test3。

我是Trees的新手,这个话题让我有些困惑,您的帮助倍受赞赏。

编辑:添加了视觉表示。

2 个答案:

答案 0 :(得分:1)

一种简单的方法是跟踪父节点,然后从孩子的树上跟随父节点:

Node currentNode = ...
ArrayList<Node> path = new ArrayList<>();
while(currentNode != null){
    path.add(currentNode);
    currentNode = currentNode.getParent();
}
Collections.reverse(path);

因此您的Node类将需要一个新的构造函数:

class Node {
    String data;
    ArrayList<Node> children;
    Node parent;
    Node(Node parent, String data){
        // ...
    }
    // ...
    // Null if this is the root, else returns the parent node
    public Node getParent(){ return parent; }
}

答案 1 :(得分:1)

public class Tree {

    private final Node root = new Node(null, null);

    public boolean isEmpty() {
        return root.children.isEmpty();
    }

    public void add(String path) {
        Node parent = root;

        for (String data : path.split("/")) {
            Node node = parent.getChild(data);

            if (node == null)
                parent.children.add(node = new Node(data, parent));

            parent = node;
        }
    }

    public Node get(String path) {
        Node parent = root;

        for (String data : path.split("/")) {
            Node node = parent.getChild(data);

            if (node == null)
                return null;

            parent = node;
        }

        return parent;
    }

    public static final class Node {

        private final String data;
        private final Node parent;
        private final List<Node> children = new LinkedList<>();

        public Node(String data, Node parent) {
            this.data = data;
            this.parent = parent;
        }

        public List<Node> getChildren() {
            return Collections.unmodifiableList(children);
        }

        public Node getChild(String data) {
            for (Node node : children)
                if (node.data.equals(data))
                    return node;

            return null;
        }

        public String getPath() {
            Deque<String> nodes = new LinkedList<>();
            Node node = this;

            while (node.parent != null) {
                nodes.addFirst(node.data);
                node = node.parent;
            }

            return String.join("/", nodes);
        }

        @Override
        public String toString() {
            return data;
        }
    }

    public static void main(String... args) {
        Tree tree = new Tree();
        tree.add("test/test2/test3");
        tree.add("test/test5/test2");
        tree.add("test/test7/test5/test4");
        tree.add("test/test7/test5/test9");

        Node node = tree.get("test/test7/test5/test9");
        String path = node.getPath();
    }

}