Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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,我正在编写一些使用树的代码(可以有无限个节点但没有交叉的常规树,即两个父节点不会指向同一个子节点)。无论如何,有两件事: 1) 在树中查找子树有什么著名的算法吗 2) 是否有任何Java库(或与此相关的库)已经实现了此算法?即使没有,有人能推荐任何好的通用Java树库吗 我想使用这些树来保存树格式的数据,而不是它们的搜索功能 更进一步:我使用树作为游戏的一部分来记录特定事件发生时发生的事情。例如,A可以击中B,B可以击中两个A,A可以击中另外两个A,等等 这看起来像: A |

我正在编写一些使用树的代码(可以有无限个节点但没有交叉的常规树,即两个父节点不会指向同一个子节点)。无论如何,有两件事:

1) 在树中查找子树有什么著名的算法吗

2) 是否有任何Java库(或与此相关的库)已经实现了此算法?即使没有,有人能推荐任何好的通用Java树库吗

我想使用这些树来保存树格式的数据,而不是它们的搜索功能

更进一步:我使用树作为游戏的一部分来记录特定事件发生时发生的事情。例如,A可以击中B,B可以击中两个A,A可以击中另外两个A,等等

这看起来像:

    A
    |
    B
   /
  A 
 / \  
A   A
   / \
  A   A
当然不仅仅是A和B。我想做的是(对于成就系统而言)能够判断A何时达到两个A:

  A
 / \
A   A

我希望能够轻松地知道第一棵树是否包含该子树。如果不需要的话,我不想写所有的代码:)

你在寻找子树上的任何特定约束吗?如果不是,l应该足以识别子树(基本上将每个节点视为子树的根)

我相信您会发现,树所需的API因您的特定应用程序而有很大差异,以至于通用实现不是很有用。也许如果你能告诉我们这棵树将用于什么样的应用,我们可以提供细节


此外,如果您只是使用一棵树来存储数据,您可能会问自己为什么需要一棵树。这个答案也应该回答我上一段中的问题。

我想知道是否有一个比简单遍历更有效的Knuth算法的扩展…

看起来像一个简单的算法:在游戏树中找到搜索树的根,并检查搜索树的子节点是否是游戏树上的孩子们

根据你的解释,我不确定搜索树

  A
 / \
A   A
应匹配此树:

  A
 /|\
A C A
(即,如果不匹配的孩子应该被忽略。)

不管怎样,这是我刚刚玩弄过的代码。这是一个完全运行的示例,附带一个main方法和一个简单的
节点
类。尽情玩吧:

import java.util.Vector;

public class PartialTreeMatch {
    public static void main(String[] args) {
        Node testTree = createTestTree();
        Node searchTree = createSearchTree();

        System.out.println(testTree);
        System.out.println(searchTree);

        partialMatch(testTree, searchTree);
    }

    private static boolean partialMatch(Node tree, Node searchTree) {
        Node subTree = findSubTreeInTree(tree, searchTree);
        if (subTree != null) {
            System.out.println("Found: " + subTree);
            return true;
        }
        return false;
    }

    private static Node findSubTreeInTree(Node tree, Node node) {
        if (tree.value == node.value) {
            if (matchChildren(tree, node)) {
                return tree;
            }
        }

        Node result = null;
        for (Node child : tree.children) {
            result = findSubTreeInTree(child, node);

            if (result != null) {
                if (matchChildren(tree, result)) {
                    return result;
                }
            }
        }

        return result;
    }

    private static boolean matchChildren(Node tree, Node searchTree) {
        if (tree.value != searchTree.value) {
            return false;
        }

        if (tree.children.size() < searchTree.children.size()) {
            return false;
        }

        boolean result = true;
        int treeChildrenIndex = 0;

        for (int searchChildrenIndex = 0;
                 searchChildrenIndex < searchTree.children.size();
                 searchChildrenIndex++) {

            // Skip non-matching children in the tree.
            while (treeChildrenIndex < tree.children.size()
                  && !(result = matchChildren(tree.children.get(treeChildrenIndex),
                                              searchTree.children.get(searchChildrenIndex)))) {
                treeChildrenIndex++;
            }

            if (!result) {
                return result;
            }
        }

        return result;
    }

    private static Node createTestTree() {
        Node subTree1 = new Node('A');
        subTree1.children.add(new Node('A'));
        subTree1.children.add(new Node('A'));

        Node subTree2 = new Node('A');
        subTree2.children.add(new Node('A'));
        subTree2.children.add(new Node('C'));
        subTree2.children.add(subTree1);

        Node subTree3 = new Node('B');
        subTree3.children.add(subTree2);

        Node root = new Node('A');
        root.children.add(subTree3);

        return root;
    }

    private static Node createSearchTree() {
        Node root = new Node('A');
        root.children.add(new Node('A'));
        root.children.add(new Node('A'));

        return root;
    }
}

class Node {
    char value;
    Vector<Node> children;

    public Node(char val) {
        value = val;
        children = new Vector<Node>();
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();

        sb.append('(');
        sb.append(value);

        for (Node child : children) {
            sb.append(' ');
            sb.append(child.toString());
        }

        sb.append(')');

        return sb.toString();
    }
}
import java.util.Vector;
公共类PartialTreeMatch{
公共静态void main(字符串[]args){
节点testTree=createTestTree();
节点searchTree=createSearchTree();
System.out.println(testTree);
System.out.println(searchTree);
partialMatch(测试树、搜索树);
}
私有静态布尔partialMatch(节点树、节点搜索树){
节点子树=findSubTreeInTree(树,搜索树);
if(子树!=null){
System.out.println(“发现:+子树);
返回true;
}
返回false;
}
私有静态节点findSubTreeInTree(节点树,节点节点){
if(tree.value==node.value){
if(匹配子级(树、节点)){
回归树;
}
}
节点结果=null;
for(节点子节点:tree.children){
结果=findSubTreeInTree(子节点、节点);
如果(结果!=null){
if(匹配子项(树、结果)){
返回结果;
}
}
}
返回结果;
}
私有静态布尔匹配子级(节点树、节点搜索树){
if(tree.value!=searchTree.value){
返回false;
}
if(tree.children.size()
如果有一棵大的、静态的树,并且您将在同一棵大树中搜索多个子树,那么您可能希望使用其所有子树的哈希集对每个节点进行注释,注释深度取决于您愿意在该功能上花费的存储量。T