二叉树遍历:前序、中序、后序

本文详细介绍了二叉树的前序、中序和后序遍历的递归与非递归实现,并通过实例演示了如何从给定的前序和中序遍历结果推导出后序遍历结果。此外,还探讨了不同遍历方式之间的转换条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 二叉树三种遍历的递归、非递归实现

首先定义一棵二叉树的结构:

 

/**
 * @Description 二叉树
 * @Author lilong
 * @Date 2019-02-27 10:23
 */
public class BinTreeNode {
    private int data;
    private BinTreeNode left;
    private BinTreeNode right;

    public int getData() {
        return data;
    }

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

    public BinTreeNode getLeft() {
        return left;
    }

    public void setLeft(BinTreeNode left) {
        this.left = left;
    }

    public BinTreeNode getRight() {
        return right;
    }

    public void setRight(BinTreeNode right) {
        this.right = right;
    }
}

然后是3种遍历的递归、非递归实现:

 

import java.util.Stack;

/**
 * @Description 前序遍历、中序遍历、后序遍历
 * @Author lilong
 * @Date 2019-02-27 11:26
 */
public class TraverseBinTree {
    /* 递归 */
    /**
     * 前序遍历(递归)
     * @param root
     */
    public void preOrderRecursive(BinTreeNode root) {
        if (root == null) {
            return;
        }

        System.out.println(root.getData());
        preOrderRecursive(root.getLeft());
        preOrderRecursive(root.getRight());
    }

    /**
     * 中序遍历(递归)
     * @param root
     */
    public void inOrderRecursive(BinTreeNode root) {
        if (root == null) {
            return;
        }

        preOrderRecursive(root.getLeft());
        System.out.println(root.getData());
        preOrderRecursive(root.getRight());
    }

    /**
     * 后序遍历(递归)
     * @param root
     */
    public void postOrderRecursive(BinTreeNode root) {
        if (root == null) {
            return;
        }

        preOrderRecursive(root.getLeft());
        preOrderRecursive(root.getRight());
        System.out.println(root.getData());
    }


    /* 非递归 */
    /**
     * 前序遍历
     * @param root
     */
    public void preOrder(BinTreeNode root) {
        if (root == null) {
            return;
        }

        Stack<BinTreeNode> stack = new Stack<BinTreeNode>();
        while (true) {
            while (root != null) {
                System.out.println(root.getData());
                stack.push(root);
                root = root.getLeft();
            }

            if (stack.isEmpty()) {
                break;
            }

            root = stack.pop();
            root = root.getRight();
        }
    }

    /**
     * 中序遍历
     * @param root
     */
    public void inOrder(BinTreeNode root) {
        if (root == null) {
            return;
        }

        Stack<BinTreeNode> stack = new Stack<BinTreeNode>();
        while (true) {
            while (root != null) {
                stack.push(root);
                root = root.getLeft();
            }

            if (stack.isEmpty()) {
                break;
            }

            root = stack.pop();
            System.out.println(root.getData());
            root = root.getRight();
        }
    }

    /**
     * 后序遍历
     * @param root
     */
    public void postOrder(BinTreeNode root) {
        if (root == null) {
            return;
        }

        Stack<BinTreeNode> stack = new Stack<BinTreeNode>();
        while (true) {
            if (root != null) {
                stack.push(root);
                root = root.getLeft();
            } else {
                if (stack.isEmpty()) {
                    System.out.println("Stack is empty.");
                    return;
                } else {
                    if (stack.peek().getRight() == null) {
                        root = stack.pop();
                        System.out.println(root.getData());
                        if (root == stack.peek().getRight()) {
                            System.out.println(stack.peek().getData());
                            stack.pop();
                        }
                    }

                    if (!stack.isEmpty()) {
                        root = stack.peek().getRight();
                    } else {
                        root = null;
                    }
                }
            }
        }
    }
}

最后测试下:

/**
 * @Description 测试
 * @Author lilong
 * @Date 2019-02-27 11:35
 */
public class Test {
    public static void main(String[] args) {
        BinTreeNode node1 = new BinTreeNode();
        node1.setData(2);
        node1.setLeft(null);
        node1.setRight(null);

        BinTreeNode node2 = new BinTreeNode();
        node2.setData(3);
        node2.setLeft(null);
        node2.setRight(null);

        BinTreeNode root = new BinTreeNode();
        root.setData(1);
        root.setLeft(node1);
        root.setRight(node2);

        TraverseBinTree traverseBinTree = new TraverseBinTree();
//        traverseBinTree.preOrderRecursive(root);
//        traverseBinTree.inOrderRecursive(root);
//        traverseBinTree.postOrderRecursive(root);
//        traverseBinTree.preOrder(root);
//        traverseBinTree.inOrder(root);
        traverseBinTree.postOrder(root);
    }
}

 

2.二叉树经典问题

根据前序遍历、中序遍历推出后序遍历。

前序:A B D E C F

中序:D B E A F C

 

前序遍历最左边的节点是根节点,此处是A,然后在中序遍历中找到A的位置,左边是左子树,右边是右子树。

 

以此类推,得到:

问:是否任意给定两种遍历方式就能得到另一种?

答:不是,这两种方式中必须有一种是中序遍历。

 

扩展:如果不是二叉树,而是一颗普通树,怎么遍历?

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值