【算法007】二叉树遍历(递归&非递归方式)

前序遍历: 先输出父节点,再遍历左子树和右子树
中序遍历: 先遍历左子树,再输出父节点,再遍历右子树
后序遍历: 先遍历左子树,再遍历右子树,最后输出父节点
小结: 看输出父节点的顺序,就确定是前序,中序还是后序

数据结构:

package com.example.chyer.demo;

import java.util.Stack;

public class Test {

    private String v;
    private Test left;
    private Test right;

    public static void main(String[] args) {
        // 初始化二叉树
        Test parent = new Test();
        parent.v = "4";
        parent.left = new Test();
        parent.left.v = "2";
        parent.left.left = new Test();
        parent.left.left.v = "1";
        parent.left.right = new Test();
        parent.left.right.v = "3";
        parent.right = new Test();
        parent.right.v = "6";
        parent.right.left = new Test();
        parent.right.left.v = "5";

        System.out.println("先序遍历:");
        parent.preOrder();
        System.out.println("中序遍历:");
        parent.infixOrder();
        System.out.println("后序遍历:");
        parent.postOrder();
        System.out.println("先序非递归:");
        parent.先序非递归(parent);
        System.out.println("中序非递归:");
        parent.中序非递归(parent);
        System.out.println("后序非递归:");
        parent.后序非递归(parent);
    }

    public String toString() {
        return this.v;
    }

    //编写前序遍历的方法
    public void preOrder() {
        System.out.println(this); //先输出父结点
        //递归向左子树前序遍历
        if (this.left != null) {
            this.left.preOrder();
        }
        //递归向右子树前序遍历
        if (this.right != null) {
            this.right.preOrder();
        }
    }

    //中序遍历
    public void infixOrder() {

        //递归向左子树中序遍历
        if (this.left != null) {
            this.left.infixOrder();
        }
        //输出父结点
        System.out.println(this);
        //递归向右子树中序遍历
        if (this.right != null) {
            this.right.infixOrder();
        }
    }

    //后序遍历
    public void postOrder() {
        if (this.left != null) {
            this.left.postOrder();
        }
        if (this.right != null) {
            this.right.postOrder();
        }
        System.out.println(this);
    }

    public static void 先序非递归(Test root) {
        Stack<Test> stack = new Stack<>();
        Test node = root;
        //节点不为空或者栈不为空都要循环
        while (node != null || !stack.empty()) {
            // 1. 输出根节点的值
            // 2. 保存根节点(方便后面找右节点)
            // 3. 找到最左节点
            while (node != null) {
                System.out.println(node.v);
                stack.push(node);
                node = node.left;
            }

            //找到右节点
            if (!stack.empty()) {
                node = stack.pop();
                node = node.right;
            }
        }
    }

    public static void 中序非递归(Test root) {
        Stack<Test> stack = new Stack<>();
        Test node = root;
        //节点不为空或者栈不为空都要循环
        while (node != null || !stack.empty()) {
            // 1. 保存根节点(方便后面找右节点)
            // 2. 找到最左节点
            while (node != null) {
                stack.push(node);
                node = node.left;
            }

            if (!stack.empty()) {
                node = stack.pop();
                System.out.println(node.v);
                node = node.right;
            }
        }
    }

    public static void 后序非递归(Test root) {
        Stack<Test> stack = new Stack<>();
        Test node = root;
        Test lastVisit = root;
        while (node != null || !stack.empty()) {
            while (node != null) {
                stack.push(node);
                node = node.left;
            }
            //查看当前栈顶元素
            node = stack.peek();
            //如果其右子树也为空,或者右子树已经访问
            //则可以直接输出当前节点的值
            if (node.right == null || node.right == lastVisit) {
                System.out.println(node.v);
                stack.pop();
                // 记录当前输出结果,以备右子树判断
                lastVisit = node;
                node = null;
            } else {
                //否则,继续遍历右子树
                node = node.right;
            }
        }
    }
}

运行结果:

发布了29 篇原创文章 · 获赞 5 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/chyercn/article/details/103234266