二叉树的前序、中序、后序遍历实现(递归+非递归)

        把LeetCode上二叉树的三序遍历做了,有个问题。本来想直接将LinkedList清空再重新放的,结果怎么搞都不行。还是对C语言指针概念匮乏啊,汇编也没学过的我哭qq。不过我通过重新new对象还是达到了想要的结果。

        List<Integer> list = new LinkedList<>();
        ......
        list = null;
        list = new LinkedList<>();

        这样就搞定了。将list指向新的堆空间。




一、二叉树的前序遍历

        二叉树的前序遍历其实就是先访问根结点,再前序遍历根结点的左子树,最后前序遍历根结点的右子树。


Alt

1、递归版

        递归版很容易想,直接根据定义一步到位。

	private void preOrderTraversal(Node<E> node) {
        if (node == null)
            return;
        System.out.print(node.element + " ");    
        preOrderTraversal(node.left);
        preOrderTraversal(node.right);
    }



2、非递归版

        观察前序遍历的访问顺序,一路往左访问,访问右结点的时候和之前往左遍历的顺序是相反的,可以借助栈将右子树入栈,不能往左访问的时候就出栈,不断循环,栈为空则遍历结束。

	private void preOrder(Node<E> node) {
        Stack<Node<E>> stack = new Stack<>();
		while(node != null || !stack.isEmpty()) {
            if(node != null) {
                System.out.print(node.element + " ");
                if(node.right != null) {
                    stack.push(node.right);
                }
                node = root.left;
            } else {
                node = stack.pop();
            }
        }
    }




二、二叉树的中序遍历

        二叉树的中序遍历其实就是先中序遍历根结点的左子树,再访问根结点,最后中序遍历根结点的右子树。

Alt

1、递归版

        根据定义一步到位。

	private void inOrderTraversal(Node<E> node) {
        if (node == null)
            return;
        inOrderTraversal(node.left);
        System.out.print(node.element + " ");     
        inOrderTraversal(node.right);
    }



2、非递归版

        观察中序遍历的访问顺序,一路往左遍历,先要访问的是不能再往左走的结点,访问左结点的顺序和往左遍历的顺序也是相反的,借助栈将一路往左时候经历的结点都入栈。不能往左的时候,将栈顶元素弹出并访问,并看看弹出的结点是否有右结点,不断循环,栈为空则遍历结束。

	private void inOrder(Node<E> node) {
        Stack<Node<E>> stack = new Stack<>();
        while(node != null || !stack.isEmpty()) {
            if(node != null) {
                stack.push(node);
                node = node.left;
            } else {
                node = stack.pop();
                result.add(node.val);
                node = node.right;
            }
        }
    }




三、二叉树的后序遍历

       二叉树的后序遍历其实就是先后序遍历根结点的左子树,再后序遍历根结点的右子树,最后访问根结点。

Alt

1、递归版

       根据定义一步到位。

	private void postOrderTraversal(Node<E> node) {
        if (node == null)
            return;
        postOrderTraversal(node.left);
        postOrderTraversal(node.right);
        System.out.print(node.element + " ");   
    }



2、非递归版

       观察后序遍历的访问顺序,其实是先某个结点的左结点,再访问它的右结点,最后访问自己。借助栈按照和访问时候反着的顺序将结点依次入栈。当遇到叶子结点或者上次弹出结点的父结点是这次栈顶的结点的时候,就从栈顶弹出元素并访问。栈为空,遍历结束。

	private void postOrder(Node<E> node) {
        Stack<Node<E>> stack = new Stack<>();
        stack.push(node);
        Node formerNode = null;
        while(!stack.isEmpty()) {
            Node top = stack.peek();
            if((top.left == null && top.right == null) || (formerNode != null && (top.left == formerNode || top.right == formerNode))) {
                formerNode = stack.pop();
                System.out.print(formerNode.element + " ");   
            } else {
                if(top.right != null) {
                    stack.push(top.right);
                }
                if(top.left != null) {
                    stack.push(top.left);
                }
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:黑客帝国 设计师:我叫白小胖 返回首页
评论

打赏作者

cj1561435010

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值