[英]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项目,以了解如何完成。
[编辑:减轻一些重量]
为您的树编写一个迭代器,该迭代器可以从任何节点初始化并使用前/后/后顺序遍历(当然,它应该是双向的)。 基本上,这是在编写一种简单的算法,至少对我来说,这是基本的。 有了迭代器后,您所需要做的就是将您的方法迭代到下一个节点,该节点是叶子,并且条件满足该条件。 如果您在任何特定部分上遇到问题,请提出问题,我会改善答案。
基于您已经定义了接口,并且您说图形遍历库太重的事实,您可能应该自己编写。 这绝对是微不足道的代码。 (如果需要帮助, 此页面包含一些代码。)
(对您的API的一个建议是:不要在Node
上放置一个boolean isRoot();
方法,除非您有充分的理由这样做,否则这会浪费一些位。构建树的代码应仅引用根节点)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.