简体   繁体   English

深度优先递归遍历树

[英]Traversing a tree recursively in depth first problems

I'm trying to traverse a tree using ANTLR tree commands and recursion. 我正在尝试使用ANTLR树命令和递归遍历一棵树。 The code I currently have is: 我目前拥有的代码是:

public void traverseTree(Tree tree){
        int counter = 0;
        System.out.println(tree.toString());
        if (tree.getChildCount() > 0 && tree.getChild(0) != null){
            System.out.println(tree.toString() + counter++);
            tree = tree.getChild(0);
            traverseTree(tree);

        }
        while (tree.getParent().getChild(tree.getChildIndex() + 1) != null){
            System.out.println(tree.toString() + counter++);
            tree = tree.getParent().getChild(tree.getChildIndex() + 1);
            traverseTree(tree);

        }
    }

But, well, it's not working. 但是,嗯,这是行不通的。 I'm getting a lot of the entries in the tree, but in no obvious order. 我在树中得到了很多条目,但是顺序不明显。 Can anyone see where I'm going wrong? 谁能看到我要去哪里错了?

Thanks. 谢谢。

EDIT: 编辑:

Comment I made below that should have been here to begin with: 我在下面提出的评论应该从这里开始:

Sorry, I should have removed the print statements, they were just there to try and debug it. 抱歉,我应该删除打印语句,他们只是在那里尝试对其进行调试。 The problem I'm encountering is that it should only search the node it starts on and any siblings of that node, it shouldn't go up a level, but it does, it prints everything. 我遇到的问题是,它应该仅搜索它开始的节点以及该节点的任何同级节点,而不应该向上搜索某个级别,但是会搜索所有内容。 (I'll edit this into the main, it should have been there to begin with, sorry). (我将其编辑为主要内容,抱歉,它应该从那里开始)。

I managed to get the code working eventually like so: 我设法使代码最终像下面这样工作:

public void traverseTree(Tree tree){
        System.out.println(tree);
        if (tree.getChild(0) != null){
            traverseTree(tree.getChild(0));
        }
        if(tree.getParent().getChildCount() > 1){
            if(tree.getParent().getChild(tree.getChildIndex() + 1) != null)
            traverseTree(tree.getParent().getChild(tree.getChildIndex() + 1));
        }
    }

The easiest way to ensure it never goes up a level is to ensure you never call getParent() . 确保它永远不会升级的最简单方法是确保您永远不要调用getParent() If you have no idea there's an upper level, you can't go there. 如果您不知道那里有高层,那么您就不能去那里。

public void traverseTree(Tree tree) {

    // print, increment counter, whatever
    System.out.println(tree.toString());

    // traverse children
    int childCount = tree.getChildCount();
    if (childCount == 0) {
        // leaf node, we're done
    } else {
        for (int i = 0; i < childCount; i++) {
            Tree child = tree.getChild(i);
            traverseTree(child);
        }
    }
}

The whole point of recursion is that you don't need to go back up. 递归的全部目的是您不需要备份。 When traverseTree() at this level finishes, the loop in the previous level will continue on to the next sibling. 当此级别的traverseTree()完成时,上一级别的循环将继续到下一个同级。

(Note that the if isn't actually necessary, unless you want to do something special when you reach a leaf node. I just put it there so the comment would make it obvious what's going on. Conceptually, it's always a good idea in recursion to start by figuring out how you know when to stop recursing.) (请注意,实际上并不需要if ,除非您要在到达叶节点时做一些特殊的事情。我只是将其放在此处,以便注释可以使正在发生的事情变得显而易见。从概念上讲,这在递归中始终是个好主意首先要弄清楚何时停止递归。)

It looks like you're printing out the same nodes several times. 看来您要多次打印相同的节点。 If you just want to print out the nodes as you go down, 如果您只想在出现故障时打印出节点,

   1
 2   3
4 5   6

Depth first - 1 2 4 5 3 6
Breadth first - 1 2 3 4 5 6

//For depth first
public void traverseTree(Tree tree){        
    System.out.println(tree.toString());
    for (int x = 0; x < tree.getChildCount(); x++)
        traverseTree(tree.getChild(x));
}

To switch to 4 5 6 2 3 1, just move the println to after the for loop. 要切换到4 5 6 2 3 1,只需在for循环之后将println移至。

Try this: 尝试这个:

int counter = 0;
public void traverseTree(Tree tree) {

    for (int i=0; i<tree.getChildCount(); i++) {
        Tree child = tree.getChild(i);
        System.out.println(tree.toString() + counter++);
        traverseTree(tree);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM