Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.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/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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.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,我有一个JSONObject,它可以有相同类型的子JSONArray。我想迭代它,找到我需要的元素并保存父元素链(例如,找到的元素是这个元素的子元素,这个元素是下一个元素的子元素,下一个元素是根元素的子元素) 目前,这是我的天真实现: private boolean found; private void searchNode(List<JSONObject> chain, JSONObject rootNode, JSONObjec

我有一个JSONObject,它可以有相同类型的子JSONArray。我想迭代它,找到我需要的元素并保存父元素链(例如,找到的元素是这个元素的子元素,这个元素是下一个元素的子元素,下一个元素是根元素的子元素)

目前,这是我的天真实现:

private boolean found;

private void searchNode(List<JSONObject> chain, 
                       JSONObject rootNode, JSONObject desiredFrame) {

    if (found)
        return;

    JSONArray children = rootNode.getJSONArray("frames");

    chain.add(rootNode);

    for (int i = 0; i < children.length(); i++) {
        JSONObject currentNode = children.getJSONObject(i);

        if (currentNode.equals(desiredNode)) {
            found = true;
            chain.add(currentNode);
            return;
        }

        searchNode(chain, currentNode, desiredNode);

        if (!found)
            chain.remove(currentNode);
    }
找到私有布尔值;
私有无效搜索节点(列表链,
JSONObject根节点,JSONObject desiredFrame){
如果(找到)
返回;
JSONArray children=rootNode.getJSONArray(“frames”);
添加(rootNode);
for(int i=0;i
我可以看到哪些问题:

private boolean found;

private void searchNode(List<JSONObject> chain, 
                       JSONObject rootNode, JSONObject desiredFrame) {

    if (found)
        return;

    JSONArray children = rootNode.getJSONArray("frames");

    chain.add(rootNode);

    for (int i = 0; i < children.length(); i++) {
        JSONObject currentNode = children.getJSONObject(i);

        if (currentNode.equals(desiredNode)) {
            found = true;
            chain.add(currentNode);
            return;
        }

        searchNode(chain, currentNode, desiredNode);

        if (!found)
            chain.remove(currentNode);
    }
  • 我不确定它是否能正常工作:)
  • 这个实现并不明显,它不是干净的代码
  • 我使用的是class字段,也许我可以避免这种用法

  • 此结构可以命名为tree,但此结构不是二进制结构。

    代码可能存在一些问题:

    • 您可以用
      searchNode
      的结果替换共享标志
      found
    • 您正在比较一个
      JSONObject
      是否等于。我建议使用
      谓词
      检查它是否为正确的节点
    • rootNode.getJSONArray(“frames”)
      可以返回
      null
      或空数组,但从不检查它
    • 您还可以使用
      Stack
      而不是
      List
      来跟踪路径。它可以简化您的算法
    例如:

    private static boolean searchNode(Stack<JSONObject> chain,
                                      JSONObject currentNode, Predicate<JSONObject> condition) throws Exception {
    
        if (condition.test(currentNode)) {
            chain.push(currentNode);
            return true;
        }
    
        JSONArray children = currentNode.getJSONArray("frames");
        if (children == null) {
            return false;
        }
    
        for (int i = 0; i < children.length(); i++) {
            if (searchNode(chain, children.getJSONObject(i), condition)) {
                chain.push(currentNode);
                return true;
            }
        }
    
        return false;
    }
    
    私有静态布尔搜索节点(堆栈链,
    JSONObject currentNode,谓词条件)引发异常{
    if(条件测试(当前节点)){
    推链(currentNode);
    返回true;
    }
    JSONArray childrent=currentNode.getJSONArray(“帧”);
    if(children==null){
    返回false;
    }
    for(int i=0;i
    代码中的一些潜在问题:

    • 您可以用
      searchNode
      的结果替换共享标志
      found
    • 您正在比较一个
      JSONObject
      是否等于。我建议使用
      谓词
      检查它是否为正确的节点
    • rootNode.getJSONArray(“frames”)
      可以返回
      null
      或空数组,但从不检查它
    • 您还可以使用
      Stack
      而不是
      List
      来跟踪路径。它可以简化您的算法
    例如:

    private static boolean searchNode(Stack<JSONObject> chain,
                                      JSONObject currentNode, Predicate<JSONObject> condition) throws Exception {
    
        if (condition.test(currentNode)) {
            chain.push(currentNode);
            return true;
        }
    
        JSONArray children = currentNode.getJSONArray("frames");
        if (children == null) {
            return false;
        }
    
        for (int i = 0; i < children.length(); i++) {
            if (searchNode(chain, children.getJSONObject(i), condition)) {
                chain.push(currentNode);
                return true;
            }
        }
    
        return false;
    }
    
    私有静态布尔搜索节点(堆栈链,
    JSONObject currentNode,谓词条件)引发异常{
    if(条件测试(当前节点)){
    推链(currentNode);
    返回true;
    }
    JSONArray childrent=currentNode.getJSONArray(“帧”);
    if(children==null){
    返回false;
    }
    for(int i=0;i
    这里有一个更好的算法来搜索您的对象

    您不必维护已找到的字段或将链作为参数传递

    相反,一旦找到对象,就使用递归调用的返回值来构建链

    List<JSONObject> search(JSONObject node, JSONObject searchTerm) {
        if (node.equals(searchTerm)) {
            List<JSONObject> chain = new List<>();
            chain.add(node);
            return chain;
        } else {
            List chain = new Collections.emptyList();
            for (JSONObject child: node.getJSONArray("frames")) {
                chain = search(child, searchTerm);
                if (chain.length > 0) {
                    chain.add(0, node);
                    break;
                }
            }
            return chain;
        }
    }
    
    列表搜索(JSONObject节点,JSONObject搜索项){
    if(node.equals(searchTerm)){
    列表链=新列表();
    添加(节点);
    返回链;
    }否则{
    List chain=new Collections.emptyList();
    for(JSONObject子节点:node.getJSONArray(“帧”)){
    链=搜索(子项、搜索项);
    如果(链长度>0){
    添加(0,节点);
    打破
    }
    }
    返回链;
    }
    }
    
    这里有一个更好的算法来搜索您的对象

    您不必维护已找到的字段或将链作为参数传递

    相反,一旦找到对象,就使用递归调用的返回值来构建链

    List<JSONObject> search(JSONObject node, JSONObject searchTerm) {
        if (node.equals(searchTerm)) {
            List<JSONObject> chain = new List<>();
            chain.add(node);
            return chain;
        } else {
            List chain = new Collections.emptyList();
            for (JSONObject child: node.getJSONArray("frames")) {
                chain = search(child, searchTerm);
                if (chain.length > 0) {
                    chain.add(0, node);
                    break;
                }
            }
            return chain;
        }
    }
    
    列表搜索(JSONObject节点,JSONObject搜索项){
    if(node.equals(searchTerm)){
    列表链=新列表();
    添加(节点);
    返回链;
    }否则{
    List chain=new Collections.emptyList();
    for(JSONObject子节点:node.getJSONArray(“帧”)){
    链=搜索(子项、搜索项);
    如果(链长度>0){
    添加(0,节点);
    打破
    }
    }
    返回链;
    }
    }
    
    您能否提供一个示例,说明JSON的外观以及您希望从中提取什么?我认为此实现很好:深度优先搜索您能否提供一个示例,说明JSON的外观以及您希望从中提取什么?我认为此实现很好:深度优先搜索正是为了做到这一点正确-你应该添加链,添加(0,父级),但不添加子级-你以前做过。捕捉得好。谢谢。只要做得正确-你应该添加链,添加(0,父级),但不添加子级-你以前做过。捕捉得好。谢谢。