了解堆栈展开的递归(树遍历)递归、堆栈、遍历

由网友(手写的从前)分享简介:我写一个程序遍历二进制搜索tree.Here是我的code:I am writing a program to traverse a binary search tree.Here's my code:Main.java public class Main {public static void main(Str...

我写一个程序遍历二进制搜索tree.Here是我的code:

I am writing a program to traverse a binary search tree.Here's my code:

Main.java

public class Main {

public static void main(String[] args) {
 BinaryTree binaryTree = new BinaryTree();
binaryTree.add(50);
binaryTree.add(40);
binaryTree.add(39);
binaryTree.add(42);
binaryTree.add(41);
binaryTree.add(43);
binaryTree.add(55);
binaryTree.add(65);
binaryTree.add(60);
binaryTree.inOrderTraversal(binaryTree.root);
} 
}

Node.java

 public class Node {
 int data;
 Node left;
 Node right;
 Node parent;


public Node(int d)
{
data = d;
left = null;
right = null;
}
}

BinaryTree.java

public class BinaryTree {
Node root = null;
public void add(int d)
{
Node newNode =  new Node(d);
if(root!=null)
{


    Node futureParent = root;
    while(true)
    {
    if(newNode.data < futureParent.data)      //going left
    {
        if(futureParent.left == null)
        {
            futureParent.left = newNode;
            newNode.parent = futureParent;
            break;
        }
        futureParent = futureParent.left;

    }
    else
    {
        if(futureParent.right == null)
        {
            futureParent.right = newNode;
            newNode.parent = futureParent;
            break;
        }
        futureParent = futureParent.right;
    }

    }

}
else
{
    root = newNode;
}
}
public void inOrderTraversal(Node node)
{
if(node!=null)
{
inOrderTraversal(node.left);
System.out.println(node.data);
inOrderTraversal(node.right);
}
}
}

据我所知,除了工艺完美,但我听不太懂的穿越。 现在,我努力着,为更好的参考树是这样的:

I understand the addition process perfectly but I have trouble understanding the traversal. Now, the tree I am working with, for better reference is this:

inOrderTraversal()函数访问50,40,然后39,最后打空做的第一个语句,如果条件为假之后,39印制中搜索右child.After这的第一条语句停止执行,堆栈退绕的第二和第三语句( inOrderTraversal(node.right)打印(节点.DATA)),从而导致打印40和穿越到41这是一部分,我不明白,也就是编译器如何重启声明1( inOrderTraversal(node.left))后,已停止,只要有新鲜的东西在堆栈中执行。

The first statement in the inOrderTraversal() function visits 50,40 then 39 and finally hits null making the if condition false after which 39 is printed and is searched for a right child.After this the first statement stops executing and the stack unwinds for the 2nd and 3rd statements(inOrderTraversal(node.right) and print(node.data)) which leads to printing 40 and traversing to 41 which is the part I dont understand, i.e. how does the compiler restart statement 1 (inOrderTraversal(node.left)) after it has stopped executing as soon as there is fresh stuff in the stack.

推荐答案

您code没有工作,因为它是,它会遍历永远在节点39的方法inOrderTraversal()确实会向左走节点,但周期过它,而永远的,因为。每个堆栈帧的变量它自己的拷贝。当进入方法,变量节点获取作为参数传递的对象引用的副本。

Your code doesn't work as it is, it will iterate forever over the node 39. The method inOrderTraversal() will indeed go to the left node, but will cycle over it forever because of the while. Each stack frame has it's own copy of the variables. When entering the method, variable node gets a copy of the object reference passed as argument.

要想想递归的一种方法是类似于使用whil​​e循环,但不是同时,如果你有一个。这里的方法应该是什么样子:

One way to think about recursion is that is similar to using a while loop, but instead of while, you have an if. Here's how the method should look like:

    public void inOrderTraversal(Node node) {
    if (node != null) {
        inOrderTraversal(node.left);
        System.out.println(node.data);
        inOrderTraversal(node.right);
    }
}

在遍历树,你想先打印较小的值,它存储在最左边的节点,让你用 inOrderTraversal(node.left); 来到如果。当你在一个空的节点到达,这意味着它的母公司是最左边的节点,所以你打印。之后,你去合适的节点,并重复上述过程。这就像分割树在较小的子树,直到你无法将它们更多,并打印自己的价值。

When you traverse the tree, you want to print first the smaller value, which is stored in left most node, so you use inOrderTraversal(node.left); to get to if. When you arrive at a null node, this means it's parent is the left-most node, so you print it. After that you go to the right node and repeat the process. It's like splitting the tree in smaller sub trees until you can't divide them any more and print their value.

每次调用一个方法(递归或没有),一个新的堆栈帧分配(压入堆栈),并且该方法完成后,栈中删除(POP),释放垃圾回收的空间。这些堆栈帧只是一个临时的空间,局部变量住。对象的成员变量住在称为具有更长的寿命的持续时间比在堆栈堆另一个地方。

Each time you call a method (recursive or not), a new stack frame is allocated (push onto the stack) and after the method finishes, the stack is removed (pop), freeing the space for garbage collection. These stacks frames are only a temporary space where local variables live. The object member variables live in another place called the heap which has a longer life duration than the stack.

JVM的处理这些空间的分配,并根据对象/变量的生活垃圾收集器释放它们。根据他们住多大,有几个代(这就是他们的称呼)。所有启动伊甸园(年轻)的产生,如果垃圾回收器不会回收空间,因为他们还活着,他们被转移到幸存者一代,在这之后,如果他们仍然没有收集,他们移动到最后一个,年老代。对象住的时间越长,对罕见的,他们由GC进行检查。这意味着,尽管在伊甸园中的对象被收集pretty的快,世代其余​​的检查没有那么频繁。还有一个叫永久代(PermGen的)另一个空间,常量曾经居住(如字符串),并在类存储。

The JVM handles the allocation of these spaces and the garbage collector frees them depending on the life of objects/variables. Depending on how much they live, there are a few generations (that's what they are called). All start on the eden (young) generation and if the garbage collector doesn't reclaim the space since they are still alive, they are moved to the survivor generation, after which if they still aren't collected, they move to the last one, the tenured generation. The longer the objects live, the rarer they are checked by the GC. This means that while the objects in the eden are collected pretty fast, the rest of the generations are checked not so often. There is also another space called the permanent generation (permgen) where constants used to live (like string literals) and where classes are stored.

阅读全文

相关推荐

最新文章