java实现二叉树遍历

二叉树的遍历是对二叉树的一种基本操作,一般可以分为递归遍历和非递归遍历,本文就直接贴代码了,二叉树图如下:

先贴树节点实体类:

package structure;

import lombok.Data;

/**
 * 节点实例
 * Created by xujia on 2019/5/27
 */
@Data
public class BinaryTreeNode {

    /**
     * 节点数据
     */
    private String value;
    /**
     * 左子节点
     */
    private BinaryTreeNode leftChild;
    /**
     * 右子节点
     */
    private BinaryTreeNode rightChild;

    public BinaryTreeNode(String value, BinaryTreeNode leftChild, BinaryTreeNode rightChild) {
        this.value = value;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
    }
}

测试类,注释已经挺详细了:

package structure;

import org.junit.Test;

import java.util.Stack;

/**
 * Created by xujia on 2019/5/27
 */
public class StackTest {


    /**
     * 初始化一颗二叉树
     * @return
     */
    private BinaryTreeNode initBinaryTreeNode() {
        BinaryTreeNode Fnode = new BinaryTreeNode("F", null, null);
        BinaryTreeNode Cnode = new BinaryTreeNode("C", Fnode, null);
        BinaryTreeNode Enode = new BinaryTreeNode("E", null, null);
        BinaryTreeNode Dnode = new BinaryTreeNode("D", null, null);
        BinaryTreeNode Bnode = new BinaryTreeNode("B", Dnode, Enode);
        BinaryTreeNode root = new BinaryTreeNode("A", Bnode, Cnode);
        return root;
    }

    @Test
    public void test() {
        BinaryTreeNode root = initBinaryTreeNode();
        System.out.println("非递归后序遍历(采用两个栈的方式):");
        postOrder(root);
        System.out.println();

        System.out.println("非递归后序遍历(采用一个栈的方式):");
        postOrderWithOneStack(root);
        System.out.println();

        System.out.println("递归后序遍历:");
        postOrderWithRecursion(root);
        System.out.println();

        System.out.println("非递归先序遍历:");
        preOrder(root);
        System.out.println();

        System.out.println("递归先序遍历:");
        priOrderWithRecursion(root);
        System.out.println();

        System.out.println("非递归中序遍历:");
        inOrder(root);
        System.out.println();

        System.out.println("递归中序遍历:");
        inOrderWithRecursion(root);
    }

    /**
     * 非递归后序遍历二叉树,逆向思维
     * 如果使用两个栈,可以在最后获取到一个完整数据的栈,你可以对该栈做操作,当然也可以使用一个栈来进行遍历,此时则做不到如上业务需求
     * 本方法采取的是利用两个栈变量来遍历,逻辑更清晰
     * 利用栈的先进后出特性,整体思想是先将所有数据按后序遍历的反序即根右左的顺序入栈,最后对栈执行出栈操作,具体操作为:
     * 1、先对根节点执行入栈操作,此时存在栈1,栈2
     * 2、然后不断搜索右子节点,并执行入栈操作,直到右子节点为空
     * 3、此时对栈1执行出栈操作开始向上遍历,并取出左子节点继续循环入栈,直到栈1为空并且当前节点为空
     * @param root 根节点
     */
    private void postOrder(BinaryTreeNode root) {
        if (null != root) {
            Stack<BinaryTreeNode> stackTemp = new Stack<>();
            Stack<BinaryTreeNode> stack = new Stack<>();
            while (null != root || !stackTemp.isEmpty()) {
                while (null != root) {
                    // 不断搜索右子节点并分别往两个栈中推元素
                    stackTemp.push(root);
                    stack.push(root);
                    root = root.getRightChild();
                }
                if (!stackTemp.isEmpty()) {
                    // 当右子节点搜索到尽头时,从临时栈中取出顶端节点开始向上反遍历
                    root = stackTemp.pop();
                    root = root.getLeftChild();
                }
            }
            while (!stack.isEmpty())
                System.out.print(stack.pop().getValue() + "\t");
        }
    }

    /**
     * 非递归后序遍历,采用一个栈的方式,正向思维
     * @param root
     */
    public void postOrderWithOneStack(BinaryTreeNode root){
        Stack<BinaryTreeNode> stack = new Stack<>();
        while (true){
            if (root != null){
                stack.push(root);
                root = root.getLeftChild();
            } else {
                if (stack.isEmpty())
                    return;
                if (null == stack.peek().getRightChild()) {
                    root = stack.pop();
                    System.out.print(root.getValue() + "\t");
                    while (root == stack.peek().getRightChild()) {
                        root = stack.pop();
                        System.out.print(root.getValue() + "\t");
                        if (stack.isEmpty()) {
                            break;
                        }
                    }
                }
                if (!stack.isEmpty())
                    root = stack.peek().getRightChild();
                else
                    root = null;
            }
        }
    }

    /**
     * 递归后序遍历
     * @param root
     */
    private void postOrderWithRecursion(BinaryTreeNode root) {
        if (null != root) {
            postOrderWithRecursion(root.getLeftChild());
            postOrderWithRecursion(root.getRightChild());
            System.out.print(root.getValue()+ "\t");
        }
    }

    /**
     * 非递归先序遍历,虽然是采用栈的方式,但是并未完全应用栈的思想,采取循环过程中输出的方式来遍历
     * @param root
     */
    private void preOrder(BinaryTreeNode root) {
        Stack<BinaryTreeNode> stack = new Stack<>();
        while (null != root || !stack.isEmpty()) {
            while (null != root) {
                System.out.print(root.getValue() + "\t");
                stack.push(root);
                root = root.getLeftChild();
            }
            if (!stack.isEmpty()) {
                root = stack.pop();
                root = root.getRightChild();
            }
        }
    }

    /**
     * 递归先序遍历
     * @param root
     */
    private void priOrderWithRecursion(BinaryTreeNode root) {
        if (null != root) {
            System.out.print(root.getValue() + "\t");
            priOrderWithRecursion(root.getLeftChild());
            priOrderWithRecursion(root.getRightChild());
        }
    }

    /**
     * 非递归中序遍历
     * @param root
     */
    private void inOrder(BinaryTreeNode root) {
        Stack<BinaryTreeNode> stack = new Stack<>();
        while (null != root || !stack.isEmpty()) {
            while (null != root) {
                stack.push(root);
                root = root.getLeftChild();
            }
            if (!stack.isEmpty()) {
                root = stack.pop();
                System.out.print(root.getValue() + "\t");
                root = root.getRightChild();
            }
        }
    }

    /**
     * 递归中序遍历
     * @param root
     */
    private void inOrderWithRecursion(BinaryTreeNode root) {
        if (null != root) {
            inOrderWithRecursion(root.getLeftChild());
            System.out.print(root.getValue() + "\t");
            inOrderWithRecursion(root.getRightChild());
        }
    }

}

输出结果:

非递归后序遍历(采用两个栈的方式):
D	E	B	F	C	A	
非递归后序遍历(采用一个栈的方式):
D	E	B	F	C	A	
递归后序遍历:
D	E	B	F	C	A	
非递归先序遍历:
A	B	D	E	C	F	
递归先序遍历:
A	B	D	E	C	F	
非递归中序遍历:
D	B	E	A	F	C	
递归中序遍历:
D	B	E	A	F	C	
Process finished with exit code 0

互勉。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清茶_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值