簡體   English   中英

java alogrithm:從樹中的任何節點中找到滿足特殊條件的前/后葉節點

[英]java alogrithm: find pre/next leaf node that meet special condition from any node in a tree

我需要編寫一個函數來從單根樹中的任何節點中找到滿足特殊條件的上一個/下一個葉子節點。 (以父級第一順序)

該API將如下所示:

Node findNextLeafNode(Node currentNode, Condition condition);
Node findPretLeafNode(Node currentNode, Condition condition);

其中currentNode是樹中的任何節點,而Node定義為:

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();
}

Condition接口定義檢查針對給定Node的約束的語義。

interface Condition{
  /** @return true if provided node meets the condition */
  boolean check(Node node);
}

我的問題:

是否存在用於這種常見情況的現有庫或算法? 我對基於堆棧或遞歸算法很開放。 偽代碼,到開源庫的鏈接,或者如果您願意共享自己的代碼,將不勝感激。

(如果沒有,我需要花時間再次發明相同的輪子,然后將其粘貼到此處以便共享。)

謝謝。

-----------------------------編寫getNext()方法........

// 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;
}

對於您的需求,這可能有些誇大其詞,但它可以滿足您的需求:

有一種圖形遍歷語言: Gremlin 通常用螺栓固定在Neo4j之類的物體上,但是可以包裝任何圖形數據結構(例如,單根有向樹)以支持API。 查看Blueprints項目,以了解如何完成。

[編輯:減輕一些重量]

也許JGraphT是您想要的。 還可以看看關於SO的這個問題 它不是完全相同的副本,但您會發現它有幫助。

為您的樹編寫一個迭代器,該迭代器可以從任何節點初始化並使用前/后/后順序遍歷(當然,它應該是雙向的)。 基本上,這是在編寫一種簡單的算法,至少對我來說,這是基本的。 有了迭代器后,您所需要做的就是將您的方法迭代到下一個節點,該節點是葉子,並且條件滿足該條件。 如果您在任何特定部分上遇到問題,請提出問題,我會改善答案。

基於您已經定義了接口,並且您說圖形遍歷庫太重的事實,您可能應該自己編寫。 這絕對是微不足道的代碼。 (如果需要幫助, 此頁面包含一些代碼。)

(對您的API的一個建議是:不要在Node上放置一個boolean isRoot();方法,除非您有充分的理由這樣做,否則這會浪費一些位。構建樹的代碼應僅引用根節點)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM