二叉树基于栈的前中后序遍历

前序遍历:首先读取根节点,再读取左孩子,再读取右孩子

中序遍历:首先读取左孩子,再读取根节点,再读取右孩子

后序遍历:首先读取左孩子,再读取右孩子,再读取根节点

代码实现:

节点类:

package org.nix.tree.binary;

/**
 * Create by [email protected] on 2018/5/4.
 * 二叉树节点
 */
public class TreeNode<T> {

    private T data;

    private TreeNode lightNode;

    private TreeNode rightNode;

    /**
     * 创建有左右子节点的节点
     * 若没有孩子则设为null
     * @param data 该节点拥有的数据
     * @param lightNode 左孩子
     * @param rightNode 右孩子
     */
    public TreeNode(T data, TreeNode lightNode, TreeNode rightNode) {
        this.data = data;
        this.lightNode = lightNode;
        this.rightNode = rightNode;
    }

    /**
     * 只有数据的节点
     * @param data 该节点拥有的数据
     */
    public TreeNode(T data) {
        this.data = data;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public TreeNode getLightNode() {
        return lightNode;
    }

    public void setLightNode(TreeNode lightNode) {
        this.lightNode = lightNode;
    }

    public TreeNode getRightNode() {
        return rightNode;
    }

    public void setRightNode(TreeNode rightNode) {
        this.rightNode = rightNode;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "data=" + data +
                ", lightNode=" + lightNode +
                ", rightNode=" + rightNode +
                '}';
    }
}

遍历方法抽象:

package org.nix.tree.base;

/**
 * Create by [email protected] on 2018/5/4.
 *
 * 遍历方法抽象
 */
public interface Traverse <T>{
    /**
     * 前序遍历
     * @param root 遍历节点
     */
    void preorder(T root);

    /**
     * 中序遍历
     * @param root 遍历节点
     */
    void inorder(T root);

    /**
     * 后序遍历
     * @param root 遍历节点
     */
    void postorder(T root);

    /**
     * 广度遍历
     * @param root 遍历节点
     */
    void layerOrder(T root);

    /**
     * 深度遍历
     * @param root 遍历节点
     */
    void deepOrder(T root);
}

遍历方法部分实现及描述

import org.nix.tree.base.Traverse;
import org.nix.tree.binary.TreeNode;

import java.util.Stack;

/**
 * Create by [email protected] on 2018/5/4.
 * <p>
 * 栈遍历二叉树
 */
public abstract class AbstractStackTraverse implements Traverse<TreeNode> {

    /**
     * 1.入栈root节点
     * 2.输出头节点,判断是否有左右节点,如有先入右节点再入左节点
     * 3.若栈空,则全部遍历完
     *
     * @param root 遍历节点
     */
    @Override
    public void preorder(TreeNode root) {

        Stack stack = getStack();
        if (root != null) {
            stack.push(root);
        }
        System.out.print("前序遍历: ");
        while (!stack.isEmpty()) {
            TreeNode treeNode = (TreeNode) stack.pop();
            System.out.print(treeNode.getData() + " ");
            if (treeNode.getRightNode() != null) stack.push(treeNode.getRightNode());
            if (treeNode.getLightNode() != null) stack.push(treeNode.getLightNode());
        }
    }

    /**
     * 1.将节点的所有左节点栈入
     * 2.栈出一个节点,输出值,判断是否有右节点,若存在,将该节点的所有做节点全出入栈
     * 3.若不存在右节点,则栈出下一个节点,输出值
     * 4.直到root == null 和 栈空
     *
     * @param root 遍历节点
     */
    @Override
    public void inorder(TreeNode root) {
        Stack stack = getStack();
        System.out.print("中序遍历: ");
        while (root != null || !stack.isEmpty()) {
            while (root != null) {
                stack.push(root);
                root = root.getLightNode();
            }
            if (!stack.isEmpty()) {
                TreeNode treeNode = (TreeNode) stack.pop();
                System.out.print(treeNode.getData() + " ");
                root = root.getRightNode();
            }
        }
    }

    /**
     * 如果节点不为空,则压栈,进入输入栈和输出栈,并将当前节点重置为当前节点的右孩子
     * 如果节点为空,则输入栈弹出,取弹出的节点的左孩子为当前节点
     * 直到输入栈为空且节点为null
     * @param root 遍历节点
     */
    @Override
    public void postorder(TreeNode root) {
        Stack input = getStack();
        Stack output = getStack(); // 中间栈存储逆后序遍历结果
        while (root!=null || !input.isEmpty()){
            if (root != null) {
                output.push(root);
                input.push(root);
                root = root.getRightNode();
            } else {
                root = (TreeNode) input.pop();
                root = root.getLightNode();
            }
        }

        while (!output.isEmpty()) {
            TreeNode treeNode = (TreeNode) output.pop();
            System.out.println(treeNode.getData());
        }
    }
    abstract Stack getStack();
}

猜你喜欢

转载自blog.csdn.net/qq_33243355/article/details/80198991
今日推荐