Java二叉樹(三)--非遞歸的中序_先序_後序遍歷二叉樹

二叉樹的遞歸遍歷非常簡單,但是非遞歸遍歷就需要一點小技巧了,否則代碼邏輯容易混亂,這裏我給每一個節點定義里加入了一個訪問標記flag,這樣可以有效避免重複訪問和代碼邏輯不清楚的問題。

二叉樹中序非遞歸遍歷代碼如下:

package binarytree;

import java.util.Stack;

/**
 * @author Gavenyeah
 * @date Time: 2016年5月13日上午8:46:38
 * @des: 
 */
//非遞歸的中序遍歷二叉樹

public class InOrder{
    public static void main(String args[]){
        Node head = new InOrder().getTree();
        new InOrder().inOrder(head);

    }
    public Node getTree(){
        Node head = new Node(1);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        Node node4 = new Node(4);
        Node node5 = new Node(5);
        Node node6 = new Node(6);
        Node node7 = new Node(7);
        Node node8 = new Node(8);

        head.left = node2;
        head.right = node3;
        node2.left = node4;
        node2.right = node5;
        node5.left = node7;
        node4.right= node6;
        node7.right= node8;

        return head;

    }
    public void inOrder(Node head){
        Stack<Node> stack  = new Stack<Node>();//用堆棧來實現非遞歸的中序遍歷二叉樹
        stack.push(head);
        Node cur = null;
        while(stack.size() > 0){
            head = stack. peek();
            while(head.left != null && head.left.flag == false){//有左子節點且未被訪問過
                head = head.left;
                stack.push(head);
            }
            //出棧並訪問節點
            cur = stack.pop();
            System.out.print(cur.data+" ");
            cur.flag = true;
            //進一步訪問右子節點
            if(cur.right != null){
                stack.push(cur.right);
                head = cur.right;
            }
        }
    }
}

先序非遞歸遍歷:

public void preOrder(Node head) {
        Stack<Node> stack = new Stack<Node>();
        stack.push(head);
        while (stack.size() > 0) {
            head = stack. peek();
            if (head.flag == false) {
                System.out.print(head.data + " ");
                head.flag = true;
            }

            while (head.left != null && head.left.flag == false) {
                head = head.left;
                System.out.print(head.data + " ");
                head.flag = true;
                stack.push(head);
            }
            head = stack.pop();// 沒有左子樹或左子樹已被訪問的節點可以直接出棧
            if (head.right != null && head.right.flag == false) {
                head = head.right;
                stack.push(head);
            } 
        }
    }

後序非遞歸遍歷:

public void postOrder(Node head){
        Stack<Node> stack = new Stack<Node>();
        stack.push(head);
        while(stack.size() > 0){
            head = stack.peek();
            while(head.left != null && head.left.flag == false || 
                    head.right != null && head.right.flag == false){
                if(head.right != null && head.right.flag == false){
                    stack.push(head.right);
                }
                if(head.left != null && head.left.flag == false){
                    stack.push(head.left);
                }
                head = stack.peek();
            }
            head = stack.pop();
            System.out.print(head.data + " ");
            head.flag = true;
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章