Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java算法:从树中的任何节点中查找满足特殊条件的前/下一个叶节点_Java_Algorithm_Tree - Fatal编程技术网

java算法:从树中的任何节点中查找满足特殊条件的前/下一个叶节点

java算法:从树中的任何节点中查找满足特殊条件的前/下一个叶节点,java,algorithm,tree,Java,Algorithm,Tree,我需要编写一个函数,从单根树中的任何节点中查找满足特殊条件的上一个/下一个叶节点。以第一顺序 API应该是这样的: Node findNextLeafNode(Node currentNode, Condition condition); Node findPretLeafNode(Node currentNode, Condition condition); 其中currentNode是树中的任意节点,节点定义为: interface Node{ /** @return the No

我需要编写一个函数,从单根树中的任何节点中查找满足特殊条件的上一个/下一个叶节点。以第一顺序

API应该是这样的:

Node findNextLeafNode(Node currentNode, Condition condition);
Node findPretLeafNode(Node currentNode, Condition condition);
其中currentNode是树中的任意节点,节点定义为:

interface Node{
    /** @return the Node's parent or null if Node is root */ 
    Node getParent();

    /** @return true if node is root */
    boolean isRoot();

    /** @return non-null array of child nodes (zero length for leaf nodes) */
    Node[] getChildren();

    /** @return the number of child nodes. If node is leaf, value is 0 */
    int getChildCount();
}
条件接口定义了根据给定节点检查约束的语义

我的问题:

对于这种常见的场景,是否有一个现有的库或算法?我对基于堆栈或递归算法持开放态度。伪代码,链接到开源库,或者如果你愿意分享你自己的代码,将不胜感激

如果没有,我需要花时间再次发明同一个轮子,然后粘贴到这里共享

谢谢

---------------编写一个方法来获取下一个

// currentNode must be descendant of root
public static Node getNextNode(Node currentNode, Node root)
{
    // 1. if is has child, next is its first child
    if (currentNode.getChildSize() > 0) {
        return currentNode.getChildren()[0];
    }
    // 2. if it has no child, check if its is the last child of his parent
    else {
        // if it is root and has no children, return null
        if (currentNode == root) {
            return null;
        }

        // else should have parent which is or under root;
        Node parent = currentNode.getParent();
        int index = getIndex(currentNode);

        if (!isLastofParent(currentNode)) {
            // ----a. if not last, next is his parent's next
            return currentNode.getParent().getChildren()[index + 1];
        }
        else {
            // ----b. if it is the last one, return its parent's next right if there is. while until root
            Node tmp = parent;
            while (tmp != root) {
                int parentIndex = getIndex(tmp);
                if (!isLastofParent(tmp)) {
                    return tmp.getParent().getChildren()[parentIndex + 1];
                }
                tmp = tmp.getParent();
            }
        }
    }
    return null;

}

private static boolean isLastofParent(Node node)
{
    if (getIndex(node) == node.getParent().getChildSize() - 1) {
        return true;
    }
    return false;
}

private static int getIndex(Node currentNode)
{
    Node parent = currentNode.getParent();
    for (int i = 0; i < parent.getChildSize(); i++) {
        if (parent.getChildren()[i] == currentNode) {
            return i;
        }
    }
    //TODO: error condition handling, will not happen if tree not change
    return -1;
}
------------完整搜索要容易得多

public static Node getNextFailNode(Node currentNode, Node root, Condition condition)
{
    boolean foundCurrentNode = false;
    Stack<Node> stack = new Stack<Node>();
    stack.push(root);
    while (!stack.isEmpty()) {
        Node tmp = stack.pop();
        System.out.println("-popup---------" +tmp+ " ");
        if (foundCurrentNode && checkCondition(tmp, condition)) {
            return tmp;
        }
        if (tmp == currentNode) {
            foundCurrentNode = true;
        }
        if (tmp.getChildSize() > 0) {

            for (int i = tmp.getChildSize() - 1; i >= 0; i--) {
                stack.push(tmp.getChildren()[i]);
            }
        }

    }
    return null;
}

这可能过分夸大了您的需求,但它可以支持您的需求:

有一种图形遍历语言:。通常固定在Neo4j之类的东西的顶部,但任何图形数据结构(例如单根有向树)都可以被包装以支持API。看看项目,了解它是如何完成的

[编辑:对于较轻的东西]


也许这就是你想要的。也来看看。它不是完全重复的,但您会发现它很有用。

为您的树编写一个迭代器,可以从任何节点初始化,并使用前/中/后顺序遍历。当然,它应该是双向的。 这基本上是写一个简单的算法,至少对我来说是基本的。 一旦你有了一个迭代器,你所需要的就是迭代到下一个节点,这个节点是一个叶子,条件对它有效。
如果您在任何特定部分遇到问题,请提问,我将改进我的答案。

基于您已经定义了接口,并且您说图形遍历库太重,您可能应该自己编写它。这将是一个绝对微不足道的代码量。如果需要帮助,包含一些代码


对您的API有一个建议:不要使用布尔isRoot;方法,这是对位的浪费,除非您有很好的理由这样做。构建树的代码应该只引用根节点。

@jkraybill:我把它放在那里了。没有位,因为它是一个接口。
public static Node getNextFailNode(Node currentNode, Node root, Condition condition)
{
    boolean foundCurrentNode = false;
    Stack<Node> stack = new Stack<Node>();
    stack.push(root);
    while (!stack.isEmpty()) {
        Node tmp = stack.pop();
        System.out.println("-popup---------" +tmp+ " ");
        if (foundCurrentNode && checkCondition(tmp, condition)) {
            return tmp;
        }
        if (tmp == currentNode) {
            foundCurrentNode = true;
        }
        if (tmp.getChildSize() > 0) {

            for (int i = tmp.getChildSize() - 1; i >= 0; i--) {
                stack.push(tmp.getChildren()[i]);
            }
        }

    }
    return null;
}