在将子节点添加到父节点Java之前如何检测循环

时间:2019-03-13 15:49:28

标签: java

我有一个如下所示的Node模型,其中包含子节点列表:

class Node {
    private String name;
    private List<Node> childNodes;

    public Node(String name, List<Node> childNodes) {
        this.name = name;
        this.childNodes = childNodes;
    }

    public Node(String name) {
        this(name, new ArrayList<>());
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Node> getChildNodes() {
        return childNodes;
    }

    public void setChildNodes(List<Node> childNodes) {
        this.childNodes = childNodes;
    }

    public void addChildNodes(Node childNode) {
        this.getChildNodes().add(childNode);
    }
}

我要做的是检查将子节点添加到父节点时是否产生循环。这里的循环表示子节点与其直接或间接父节点具有相同的名称。当检测到循环时,我还要打印出该循环中包含哪些节点。我已经完成的工作是:

    private static void findLoop(Node currentNode, String orginalNodeName, String visitedNode) {
        if (currentNode != null && !currentNode.getChildNodes().isEmpty()) {
            for (Node childNode : currentNode.getChildNodes()) {
                visitedNode = visitedNode + "->" + childNode.getName();
                if (childNode.getName().equals(orginalNodeName)) {
                    System.out.println("Loop is detected: " + visitedNode);
                }
                findLoop(childNode, orginalNodeName, visitedNode);
            }
        }
    }

我的想法是遍历所有子节点,从要检查的节点开始,然后比较当前节点是否与原始起始节点具有相同的名称,如果是,则检测到循环。

它可以工作,但是我不能正确打印循环的内容,因为它遍历父节点的所有可能的子节点,例如:

            parentNode
    node1                node2
  childNode1           childNode2
                parentNode   childChildNode2

它打印了:parentNode->node1->node2->childNode2->parentNode,我想打印的是:parentNode->node2->childNode2->parentNode

有人可以在这里给我一些提示吗?非常感谢!

1 个答案:

答案 0 :(得分:0)

由于您已经很接近要获得的结果,因此以下几条提示可以提示您如何完成任务:

  • findLoop需要返回boolean -否则您将不知道何时在递归的更高级别上停止迭代
  • visitedNode必须是List<Node> -否则,您将只能使用单个项目的名称
  • findLoop中的for(...)返回true时,方法会立即返回true -这样可以确保肯定值不会被忽略

最后,不要忘记findLoop必须从子节点开始,然后循环到父节点,而不是相反。