JAVA二叉树遍历(递归和非递归)

简介

对于二叉树来讲最主要、最基本的运算是遍历。
遍历二叉树:是指以一定的次序访问二叉树中的每个结点。所谓访问结点 是指对结点进行各种操作的简称。例如,查询结点数据域的内容,或输出它的值,或找出结点位置,或是执行对结点的其他操作。遍历二叉树的过程实质是把二叉树的结点进行线性排列的过程。假设遍历二叉树时访问结点的操作就是输出结点数据域的值,那么遍历的结果得到一个线性序列。

遍历规则

从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
 (1)访问结点本身(N),
 (2)遍历该结点的左子树(L),
 (3)遍历该结点的右子树(R)。
以上三种操作有六种执行次序:
 NLR(前序遍历–根左右)
 LNR(中序遍历–左根右)
 LRN(后序遍历–左右根)
 NRL、RNL、RLN
注意:
前三种次序与后三种次序对称,故只讨论先左后右的前三种次序。
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtlee)和R(Right subtree)又可解释为根、根的左子树和根的右子树。NLR、LNR和LRN分别又称为先根遍历、中根遍历和后根遍历。

递归遍历代码

package test.node;

public class Node {
    private Node left;
    private Node right;
    private int value;

    public Node(int value){
        this.value = value;
    }

    public Node(){}

    //前序遍历------根左右
    public static void preTraversal(Node node){
        if(node != null){
            System.out.print(node.value);
            preTraversal(node.left);
            preTraversal(node.right);
        }
    }

    //中序遍历------左根右
    public static void midTraversal(Node node){
        if(node != null){
            midTraversal(node.left);
            System.out.print(node.value);
            midTraversal(node.right);
        }
    }

    //后序遍历------左右根
    public static void behTraversal(Node node){
        if(node != null){
            behTraversal(node.left);
            behTraversal(node.right);
            System.out.print(node.value);
        }
    }

    public static void main(String[] args) {
        Node n1 = new Node(1);
        Node n2 = new Node(2);
        Node n3 = new Node(3);
        Node n4 = new Node(4);
        Node n5 = new Node(5);
        Node n6 = new Node(6);
        Node n7 = new Node(7);
        Node n8 = new Node(8);
        Node n0 = null;

        n1.left = n2;
        n1.right = n3;
        n2.left = n4;
        n2.right = n5;
        n5.right = n8;
        n3.left = n6;
        n6.right = n7;

        System.out.print("前序遍历结果为:");
        preTraversal(n1);
        System.out.println();
        System.out.print("中序遍历结果为:");
        midTraversal(n1);
        System.out.println();
        System.out.print("后序遍历结果为:");
        behTraversal(n1);
    }
}

递归遍历

//前序遍历------根左右
    public static void preTraversal(Node node){
        if(node != null){
            System.out.print(node.value);
            preTraversal(node.left);
            preTraversal(node.right);
        }
    }

    //中序遍历------左根右
    public static void midTraversal(Node node){
        if(node != null){
            midTraversal(node.left);
            System.out.print(node.value);
            midTraversal(node.right);
        }
    }

    //后序遍历------左右根
    public static void behTraversal(Node node){
        if(node != null){
            behTraversal(node.left);
            behTraversal(node.right);
            System.out.print(node.value);
        }
    }

非递归遍历

1、前序遍历
根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,再访问它的右子树。因此其处理过程如下:

 对于任一结点P:

 1)访问结点P,并将结点P入栈;

 2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;

 3)直到P为NULL并且栈为空,则遍历结束。
//先序遍历---非递归
    public static void noRecPreOrder(Node node) {
        System.out.print("二叉树非递归先序遍历:");
        LinkedList<Node> stack = new LinkedList<Node>();
        Node current = node;
        while (current != null || !stack.isEmpty()) {
            while (current != null) {
                System.out.print(current.value);// 先序
                stack.push(current);// 压入栈顶
                current = current.left;
            }
            if (!stack.isEmpty()) {
                current = stack.pop();// 移除栈顶对象,并返回该对象
                // System.out.print(current.value);//中序
                current = current.right;
                // System.out.print(current.value);//后序
            }
        }
        System.out.println();
    }

参考:

二叉树的遍历 递归非递归 思路和 java实现http://blog.csdn.net/clam_clam/article/details/6845399

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值