使用Stack修复我的“inorder树遍历”算法的实现

时间:2013-03-13 01:42:51

标签: java tree stack binary-tree tree-traversal

部分原因是我必须实现二阶树的顺序遍历的非递归方法。我有点卡住了。以下是我到目前为止的情况:

public void inorder(BinaryTree v) {
    Stack<BinaryTree> stack = new Stack<BinaryTree>();
    stack.push(v);
    System.out.println(v.getValue());

    while(!stack.isEmpty()) {
        while(v.getLeft() != null) {
            v = v.getLeft();
            stack.push(v);
            System.out.println(v.getValue());
        }

        while(v.getRight() != null) {
            v = v.getRight();
            stack.push(v);
            System.out.println(v.getValue());
        }
                stack.pop();
    }
}

我注意到它只打印出树的左侧,例如

          A
        /   \
       B     C
     /   \  /  \
    D     E F   G
   /  \
  H     I
 / \
J   K

提供A B D H J

4 个答案:

答案 0 :(得分:18)

您可以使用单个while循环大大简化上述操作:

Stack<Node> stack = new Stack<>();
Node current = root;
while(current != null || !stack.isEmpty()){
  if(current != null){
    stack.push(current);
    current = current.left;
  } else if(!stack.isEmpty()) {
    current = stack.pop();
    process(current);
    current = current.right;
  }
}

基本上,上面的代码会推动堆栈上的左分支,直到它到达分支中最左边的节点。然后它弹出并处理它(你可以打印它或用它做其他事情)然后它推动堆栈上的右分支进行处理,因为左分支和节点本身已完成。

答案 1 :(得分:6)

在你的代码之后,getLeft()部分的while循环一直向下到树的左边,然后退出。 v现在是节点J,它没有正确的子节点,因此下一个while循环不会运行。

试试这个代码示例:http://www.ashishsharma.me/2011/09/inorder-traversal-without-recursion.html

StackOverflow回答:https://stackoverflow.com/a/12718147/1178781

// Inorder traversal:
// Keep the nodes in the path that are waiting to be visited
Stack s = new Stack(); 
// The first node to be visited is the leftmost
Node node = root;
while (node != null) {
    s.push(node);
    node = node.left;
}
// Traverse the tree
while (s.size() > 0) {
    // Visit the top node
    node = (Node)s.pop();
    System.out.println((String)node.data);
    // Find the next node
    if (node.right != null) {
        node = node.right;
        // The next node to be visited is the leftmost
        while (node != null) {
            s.push(node);
            node = node.left;
        }
    }
}

答案 2 :(得分:1)

我有一个只使用一个while循环的解决方案。它类似于Giovanni的解决方案,但在我看来它看起来更干净,更易读。具体来说,该设计类似于In Order Traversal的递归解决方案,这使得它更容易理解。

public void InOrderTraversal(Node root) {

    if (root == null) return;

    Deque<Node> stack = new ArrayDeque<>();

    stack.push(root);

    while (!stack.isEmpty()) {

        Node curr = stack.peek();

        if (curr.left != null) {

            stack.push(curr.left);
            continue;
        }


        Node node_to_print = stack.pop();
        System.out.println(node_to_print.data);


        if (curr.right != null) {

            stack.push(curr.right);

        }

    }

    return;
}

注意:我使用Deque接口来实现我的堆栈。根据API,这应该是首选方法:http://docs.oracle.com/javase/7/docs/api/java/util/Stack.html

答案 3 :(得分:0)

另一个更简单的二进制遍历实现:

<android.support.design.widget.TextInputLayout
     android:id="@+id/aTIL"
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
     <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/aET" />
</android.support.design.widget.TextInputLayout>