二叉树的三种遍历实现

前言

  二叉树的三种遍历实现,即前序遍历、中序遍历、后序遍历

  github代码地址:https://github.com/Chenrencun/leetcode-learn

正文

  以下的实现是根据以下的二叉树:

 

  1、前序遍历:

  (1)递归方式:

    /**
     * 前序遍历(递归)
     * @param node
     * @param <T>
     */
    public static <T> void preOrderTraverse(TreeNode<T> node){
        if (node == null) return;
        // 先访问根节点
        System.out.println(node.getData());
        // 再前序遍历左子树
        preOrderTraverse(node.getLeftChild());
        // 最后前序遍历右子树
        preOrderTraverse(node.getRightChild());
    }

  (2)非递归方式:

    /**
     * 前序遍历(非递归)
     * @param node
     * @param <T>
     */
    public static <T> void preOrderTraverseWithStack(TreeNode<T> node){
        Stack<TreeNode<T>> stack = new Stack<>();
        TreeNode<T> treeNode = node;
        while (treeNode != null || !stack.isEmpty()){
            // 循环访问节点的左子节点,并入栈
            while (treeNode != null){
                System.out.println(treeNode.getData());
                stack.push(treeNode);
                treeNode = treeNode.getLeftChild();
            }

            // 如果节点没有左子节点,则出栈,并访问右子节点
            if (!stack.isEmpty()){
                treeNode = stack.pop();
                treeNode = treeNode.getRightChild();
            }
        }
    }

 

  执行后的结果为(GEDACHS):

 

 

  2、中序遍历

  (1)递归方式:

    /**
     * 中序遍历(递归)
     * @param node
     * @param <T>
     */
    public static <T> void inOrderTraverse(TreeNode<T> node){
        if (node == null) return;
        // 先中序遍历左子树
        inOrderTraverse(node.getLeftChild());
        // 再访问根节点
        System.out.println(node.getData());
        // 最后中序遍历右子树
        inOrderTraverse(node.getRightChild());
    }

  (2)非递归方式:

    /**
     * 中序遍历(非递归)
     * @param node
     * @param <T>
     */
    public static <T> void inOrderTraverseWithStack(TreeNode<T> node){
        Stack<TreeNode<T>> stack = new Stack<>();
        TreeNode<T> treeNode = node;
        while (treeNode != null || !stack.isEmpty()){
            while (treeNode != null) {
                stack.push(treeNode);
                treeNode = treeNode.getLeftChild();
            }

            if (!stack.isEmpty()){
                treeNode = stack.pop();
                System.out.println(treeNode.getData());
                treeNode = treeNode.getRightChild();
            }
        }
    }

 

  执行后的结果为(DEAGHCS):

 

 

  3、后序遍历:

  (1)递归方式:

    /**
     * 后序遍历(递归)
     * @param node
     * @param <T>
     */
    public static <T> void postOrderTraverse(TreeNode<T> node){
        if (node == null) return;
        // 先后序遍历左子树
        postOrderTraverse(node.getLeftChild());
        // 再后序遍历右子树
        postOrderTraverse(node.getRightChild());
        // 最后访问根节点
        System.out.println(node.getData());
    }

  (2)非递归方式:

    /**
     * 后序遍历(非递归)
     * @param node
     * @param <T>
     */
    public static <T> void postOrderTraverseWithStack(TreeNode<T> node){
        Stack<TreeNode<T>> stack = new Stack<>();
        TreeNode<T> treeNode = node;
        // 标记每次遍历最后一次访问的节点
        TreeNode<T> lastVisit = null;
        while (treeNode != null || !stack.isEmpty()){
            while (treeNode != null){
                stack.push(treeNode);
                treeNode = treeNode.getLeftChild();
            }

            if (!stack.isEmpty()){
                treeNode = stack.pop();

                // 判断节点是否有右子节点(判断lastVisit,是为了避免重复输出右子节点)
                if (treeNode.getRightChild() == null || treeNode.getRightChild() == lastVisit){
                    // 如果没有,则输出data
                    System.out.println(treeNode.getData());
                    lastVisit = treeNode;
                    treeNode = null;
                } else {
                    // 如果有,则再次入栈,并访问节点的右子节点
                    stack.push(treeNode);
                    treeNode = treeNode.getRightChild();
                }
            }
        }
    }

 

  执行后的结果为(DAEHSCG):

 

posted @ 2020-08-27 09:34  路人甲、  阅读(477)  评论(0编辑  收藏  举报