Java方式實現二叉樹的前中後序遍歷的遞歸及非遞歸算法

最近在研究數據結構算法,發現許多樹類的算法都很靈活,所以研究了一下基礎二叉樹的遞歸以及非遞歸的三種遍歷方式,在這裏記錄下來方便以後回憶。

以該樹爲例:
這裏寫圖片描述

二叉樹的遍歷爲三種:前序遍歷、中序遍歷、後續遍歷。
前序遍歷(先根遍歷):即是在二叉樹的遍歷過程中,先訪問根節點若左子樹不空則訪問左節點、若右子樹不空則訪問右節點,在訪問左右子樹時亦是先訪問根節點再訪問左節點、右節點,以此順序。
此樹的先序遍歷結果爲:631254978

中序遍歷(中跟遍歷):即是先訪問左節點,再根節點,最後右節點。
中序遍歷結果爲:123456789

後序遍歷(後跟遍歷):先訪問左節點,再右節點、最後根節點。
後序遍歷結果爲:214538796

1、遞歸方式
建立數據模型()

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;
    }
}

三種遍歷:

package Binary_tree;

public class Traverse_tree {

    /*
     * 二叉樹先序中序後序排序
     * 方式:遞歸。
     */

    //注意必須逆序簡歷,先建立子節點,再逆序往上建立,
    //因爲非葉子節點會使用到下面的節點,而初始化是按順序初始化得,不逆序建立會報錯
    public static Node init(){
        Node J = new Node(8, null, null);
        Node H = new Node(4, null, null);
        Node G = new Node(2, null, null);
        Node F = new Node(7, null, J);
        Node E = new Node(5, H, null);
        Node D = new Node(1, null, G);
        Node C = new Node(9, F, null);
        Node B = new Node(3, D, E);
        Node A = new Node(6, B, C);
        return A;  //返回根節點
    }

    //打印節點數值
    public static void printNode(Node node){
        System.out.print(node.getData());
    }

        public void preOrder(Node root){    //前序遍歷
        printNode(root);
        if(root.getLeftNode()!=null)
            preOrder(root.getLeftNode());
        if(root.getRightNode()!=null)
            preOrder(root.getRightNode());
    }

        public void inOrder(Node root){     //中序遍歷
        if(root.getLeftNode()!=null)
            inOrder(root.getLeftNode());
        printNode(root);
        if(root.getRightNode()!=null)
            inOrder(root.getRightNode());
    }

    public void postOrder(Node root){       //後續遍歷
        if(root.getLeftNode()!=null)
            postOrder(root.getLeftNode());
        if(root.getRightNode()!=null)
            postOrder(root.getRightNode());
        printNode(root);
    }

    public static void main(String[] args){
        Node node = Traverse_tree.init();
        Traverse_tree obj = new Traverse_tree();

        System.out.println("前序遍歷");
        obj.preOrder(node);
        System.out.println();

        System.out.println("中序遍歷");
        obj.inOrder(node);
        System.out.println();

        System.out.println("後續遍歷");
        obj.postOrder(node);

    }

}

2、非遞歸的三種遍歷方式:

import java.util.Stack;

public class Nontraverse_tree {

    Node node;


    public static Node_Nontraverse init(){
        Node I = new Node(8,null,null);
        Node H = new Node(4,null,null);
        Node G = new Node(2,null,null);
        Node D = new Node(1,null,G);
        Node E = new Node(5,H,null);
        Node F = new Node(7,null,I);
        Node B = new Node(3,D,E);
        Node C = new Node(9,F,null);
        Node A = new Node(6,B,C);
        return A;
    }

    public void preOrder(Node node){
        Node root = node;
        Stack<Node> stack = new Stack<Node>();
        while(root!=null||stack.size()>0){
            if(root!=null){
                stack.push(root);
                System.out.print(root.getData());
                root = root.getLeftNode();

            }
            else{
                root = stack.pop();
                root = root.getRightNode();
            }

        }
    }

    public void inOrder(Node node){
        Node root = node;
        Stack<Node> stack = new Stack<Node>();
        while(root!=null||stack.size()>0){
            if(root!=null){
                stack.push(root);

                root = root.getLeftNode();

            }
            else{
                root = stack.pop();
                System.out.print(root.getData());
                root = root.getRightNode();
            }

        }
    }

    public void postOrder(Node node){
        Node root = node;
        Stack<Node> stack = new Stack<Node>();
        Stack<Node> output = new Stack<Node>();
        while(root!=null||stack.size()>0){
            if(root!=null){
                stack.push(root);
                output.push(root);
                root = root.getRightNode();
            }
            else{
                root = stack.pop();
                root = root.getLeftNode();
            }
        }

        while(output.size()>0){
            System.out.print(output.pop().getData());
        }

    }

    public static void main(String[] args){
        Nontraverse_tree obj = new Nontraverse_tree();
        Node root = Nontraverse_tree.init();

        System.out.println("二叉樹的非遞歸前序遍歷:");
        obj.preOrder(root);
        System.out.println();

        System.out.println("二叉樹的非遞歸中序遍歷:");
        obj.inOrder(root);
        System.out.println();

        System.out.println("二叉樹的非遞歸後序遍歷:");
        obj.postOrder(root);
    }

}

原帖地址爲:

http://blog.csdn.net/jssongwei/article/details/50790253

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章