二叉树的遍历

前端之家收集整理的这篇文章主要介绍了二叉树的遍历前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

二叉树

所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。

遍历方式分别为:先序遍历、中序遍历、后序遍历。

遍历之前,我们先来创建一棵树。
首先要声明结点TreeNode类,代码如下:

public class TreeNode {
    private int val;
    private TreeNode left;
    private TreeNode right;
    public TreeNode() {
    }

    public TreeNode(int val) {
        this.val = val;
    }

    public TreeNode(int val,TreeNode left,TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
     
    // 省略get、set
}

随机创建一个tree

public class TreeBuilder {

    /**
     *                      1
     *                  /       \
     *                 2            3
     *              /   \           /   \
     *             4     5         6     7
     *             /                \
     *             8                 9
     * @return
     */
    public static TreeNode randomBuild() {
        TreeNode node8 = new TreeNode(8);
        TreeNode node9 = new TreeNode(9);
        TreeNode node7 = new TreeNode(7);
        TreeNode node6 = new TreeNode(6,null,node9);
        TreeNode node5 = new TreeNode(5);
        TreeNode node4 = new TreeNode(4,node8,null);
        TreeNode node3 = new TreeNode(3,node6,node7);
        TreeNode node2 = new TreeNode(2,node4,node5);
        TreeNode node1 = new TreeNode(1,node2,node3);

        return node1;
    }

}

使用递归的方式进行遍历

public class TreePrint1 {

    public static void main(String[] args) {
        TreeNode head = TreeBuilder.randomBuild();

        System.out.println("preorderTraversal");
        preorderTraversal(head);

        System.out.println("\n\ninorderTraversal");
        inorderTraversal(head);

        System.out.println("\n\npostorderTraversal");
        postorderTraversal(head);
    }

    /**
     * 二叉树前序遍历   根-> 左-> 右
     */
    private static void preorderTraversal(TreeNode head) {
        if (head == null) {
            return;
        }
        System.out.print(head.getVal() + " ");
        preorderTraversal(head.getLeft());
        preorderTraversal(head.getRight());
    }

    /**
     *  二叉树中序遍历   左-> 根-> 右
     */
    private static void inorderTraversal(TreeNode head) {
        if (head == null) {
            return;
        }
        inorderTraversal(head.getLeft());
        System.out.print(head.getVal() + " ");
        inorderTraversal(head.getRight());
    }

    /**
     * 二叉树后序遍历   左-> 右-> 根
     */
    private static void postorderTraversal(TreeNode head) {
        if (head == null) {
            return;
        }
        postorderTraversal(head.getLeft());
        postorderTraversal(head.getRight());
        System.out.print(head.getVal() + " ");
    }

}

使用非递归的方式进行遍历

public class TreePrint2 {

    public static void main(String[] args) {
        TreeNode head = TreeBuilder.randomBuild();

        System.out.println("preorderTraversal");
        preorderTraversal(head);

        System.out.println("\n\ninorderTraversal");
        inorderTraversal(head);

        System.out.println("\n\npostorderTraversal");
        postorderTraversal(head);
    }

    /**
     * 二叉树前序遍历   根-> 左-> 右
     */
    private static void preorderTraversal(TreeNode head) {
        if (head == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = head;
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                System.out.print(node.getVal() + " ");
                stack.push(node);
                node = node.getLeft();
            }
            if (!stack.isEmpty()) {
                node = stack.pop().getRight();
            }
        }
    }

    /**
     *  二叉树中序遍历   左-> 根-> 右
     */
    private static void inorderTraversal(TreeNode head) {
        if (head == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = head;
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                stack.push(node);
                node = node.getLeft();
            }
            if (!stack.isEmpty()) {
                node = stack.pop();
                System.out.print(node.getVal() + " ");
                node = node.getRight();
            }
        }
    }

    /**
     * 二叉树后序遍历   左-> 右-> 根
     */
    private static void postorderTraversal(TreeNode head) {
        if (head == null) {
            return;
        }
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = head;   // 当前根节点
        TreeNode last = null;   // 上一次打印的节点
        while (node != null || !stack.isEmpty()) {
            while (node != null) {
                stack.push(node);
                node = node.getLeft();
            }
            if (!stack.isEmpty()) {
                node = stack.pop();
                /*
                没有右节点,当前节点可以打印了
                当前节点的右节点就是上一次打印的节点,当前节点可以打印了
                “node = null”表示当前节点的这个分支不能再处理了,因为外层循环是“node = node.getLeft()”
                 */
                if (node.getRight() == null || node.getRight() == last) {
                    System.out.print(node.getVal() + " ");
                    last = node;
                    node = null;
                }else {
                    stack.add(node);
                    node = node.getRight();
                }

            }
        }
    }

}

猜你在找的算法相关文章