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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值