1. 程式人生 > >JAVA實現二叉樹的前、中、後序遍歷(遞迴與非遞迴)

JAVA實現二叉樹的前、中、後序遍歷(遞迴與非遞迴)

最近在面試中遇到過問到二叉樹後序遍歷非遞迴實現的方法,之前以為會遞迴的解決就OK,看來還是太心存僥倖,在下一次面試之前,特地整理一下這個問題。

首先二叉樹的結構定義,java程式碼如下:

public class Node {  
    private int data;  
    private Node leftNode;  
    private Node rightNode;  
    public Node(int data, Node leftNode, Node rightNode){  
        this.data = data;  
        this
.leftNode = leftNode; this.rightNode = rightNode; } public int getData() { return data; } public void setData(int data) { this.data = data; } public Node getLeftNode() { return leftNode; } public void setLeftNode
(Node leftNode) { this.leftNode = leftNode; } public Node getRightNode() { return rightNode; } public void setRightNode(Node rightNode) { this.rightNode = rightNode; } }

先是前、中、後序遍歷的遞迴實現,這個還是比較簡單的

public void theFirstTraversal(Node root) {  //先序遍歷  
visit(root); if (root.getLeftNode() != null) { //使用遞迴進行遍歷左孩子 theFirstTraversal(root.getLeftNode()); } if (root.getRightNode() != null) { //遞迴遍歷右孩子 theFirstTraversal(root.getRightNode()); } } public void theInOrderTraversal(Node root) { //中序遍歷 if (root.getLeftNode() != null) { theInOrderTraversal(root.getLeftNode()); } visit(root); if (root.getRightNode() != null) { theInOrderTraversal(root.getRightNode()); } } public void thePostOrderTraversal(Node root) { //後序遍歷 if (root.getLeftNode() != null) { thePostOrderTraversal(root.getLeftNode()); } if(root.getRightNode() != null) { thePostOrderTraversal(root.getRightNode()); } visit(root); }

但是有些面試官會考到非遞迴實現的思路,實際上需要借用棧的輔助實現。程式碼如下:

 public void theFirstTraversal_Stack(Node root) {  //先序遍歷  
        Stack<Node> stack = new Stack<Node>();  
        Node node = root;  
        while (node != null || stack.size() > 0) {  //將所有左孩子壓棧  
            if (node != null) {   //壓棧之前先訪問  
                visit(node);  
                stack.push(node);  
                node = node.getLeftNode();  
            } else {  
                node = stack.pop();  
                node = node.getRightNode();  
            }  
        }  
    }  

    public void theInOrderTraversal_Stack(Node root) {  //中序遍歷  
        Stack<Node> stack = new Stack<Node>();  
        Node node = root;  
        while (node != null || stack.size() > 0) {  
            if (node != null) {  
                stack.push(node);   //直接壓棧  
                node = node.getLeftNode();  
            } else {  
                node = stack.pop(); //出棧並訪問  
                visit(node);  
                node = node.getRightNode(); 
            }  
        }  
    }  

    public void thePostOrderTraversal_Stack(Node root) {   //後序遍歷  雙棧
        Stack<Node> stack = new Stack<Node>();  
        Stack<Node> output = new Stack<Node>();//構造一箇中間棧來儲存逆後序遍歷的結果  
        Node node = root;  
        while (node != null || stack.size() > 0) {  
            if (node != null) {  
                output.push(node);  
                stack.push(node);                 
                node = node.getRightNode();  
            } else {  
                node = stack.pop();               
                node = node.getLeftNode();
            }  
        }  
        System.out.println(output.size());
        while (output.size() > 0) {

            visit(output.pop());  
        }  
    }


        /** 非遞迴實現後序遍歷 單棧法*/    
    protected static void iterativePostorder3(Node p) {    
        Stack<Node> stack = new Stack<Node>();    
        Node node = p, prev = p;    
        while (node != null || stack.size() > 0) {    
            while (node != null) {    
                stack.push(node);    
                node = node.getLeft();    
            }    
            if (stack.size() > 0) {    
                Node temp = stack.peek().getRight();    
                if (temp == null || temp == prev) {    
                    node = stack.pop();    
                    visit(node);    
                    prev = node;    
                    node = null;    
                } else {    
                    node = temp;    
                }    
            }    

        }    
    }