java迭代实现二叉树先中后序遍历(非递归)

Posted PacosonSWJTU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java迭代实现二叉树先中后序遍历(非递归)相关的知识,希望对你有一定的参考价值。

【README】

本文复习了通过java迭代实现 二叉树先序,中序,后序遍历;

本文引入了 栈,替换了递归,对二叉树进行遍历

补充:使用递归遍历二叉树缺点

  • 众所周知,每次递归,实际是把方法调用帧,连同方法参数一起压入到方法栈; jvm中的方法栈的深度有限,一旦二叉树节点个数过多,可能导致栈溢出的情况
  • 我们通过压入显式栈,替换了递归,即替换了方法栈;在可能的情况下,即便二叉树节点过多,也不会报栈溢出异常;
  • 显式栈,可以用 数组来实现,不一定是 Stack类;

【1】二叉树遍历

【1.1】先序遍历

1)遍历规则

  • 对于一颗二叉树,先遍历其根节点,再遍历左孩子,最后遍历右孩子;
  • 若左孩子下面挂了一棵树(左子树),则继续遍历左子树;
  • 若右孩子下面一棵树(右子树),则继续遍历右子树;

2)先序遍历迭代实现:

/**
     * @description 先序遍历
     * @author xiao tang
     * @date 2022/11/20
     */
    public static void printByPreOrder(MyBinTree root) 
        Stack<MyBinTree> stack = new Stack<>();
        stack.push(root);

        while(!stack.isEmpty()) 
            root = stack.pop();
            if (root == null) 
                System.out.print("NULL ");
             else 
                System.out.print(root.value + " ");
                stack.push(root.right);
                stack.push(root.left);
            
        
    

// 二叉树 
public class MyBinTree 
    int value;
    MyBinTree left;
    MyBinTree right;
    public MyBinTree(int value) 
        this.value = value ;
    

【1.2】中序遍历

1)遍历规则

  • 对于一颗二叉树,先遍历左孩子,再遍历根节点,最后遍历右孩子;
  • 若左孩子下面挂了一棵树(左子树),则继续遍历左子树;
  • 若右孩子下面一棵树(右子树),则继续遍历右子树;

2)中序遍历迭代实现:

/**
     * @description 中序遍历
     * @author xiao tang
     * @date 2022/11/20
     */
    public static void printByInOrder(MyBinTree root) 
        Stack<MyBinTree> stack = new Stack<>();
        stack.push(root);

        while(!stack.isEmpty()) 
            if (root != null) 
                stack.push(root.left);
                root = root.left;
             else 
                // 左儿子或右儿子为空
                stack.pop();
                System.out.print("NULL ");
                if (!stack.isEmpty()) 
                    root = stack.pop();
                    System.out.print(root.value + " ");
                    stack.push(root.right);
                    root = root.right;
                
            
        
    

【1.3】后序遍历

1)遍历规则

  • 对于一颗二叉树,先遍历左孩子,再遍历右孩子,最后遍历根节点;
  • 若左孩子下面挂了一棵树(左子树),则继续遍历左子树;
  • 若右孩子下面一棵树(右子树),则继续遍历右子树;

2)后序遍历迭代实现:

/**
     * @description 后序遍历
     * @author xiao tang
     * @date 2022/11/20
     */
    public static void printByPostOrder(MyBinTree root) 
        Stack<MyBinTree> stack = new Stack<>();
        stack.push(root);
        // 空的右孩子哨兵, 空的左孩子哨兵为null, 以把空右孩子 与 空左孩子 区别开
        MyBinTree rightNullNode = new MyBinTree(0);

        while(!stack.isEmpty()) 
            if (root != null && root != rightNullNode) 
                stack.push(root.left);
                root = root.left;
             else 
                // 左孩子或右孩子为null
                MyBinTree lastNodeVisited = stack.pop();
                System.out.print("NULL ");
                while (!stack.isEmpty()) 
                    root = stack.peek();
                    MyBinTree rightChild = root.right != null ? root.right : rightNullNode;
                    if (rightChild == lastNodeVisited) 
                        // 若刚刚访问的节点 等于 右孩子,则根节点弹出
                        lastNodeVisited = stack.pop();
                        System.out.print(lastNodeVisited.value + " ");
                     else 
                        stack.push(rightChild);
                        root = rightChild;
                        break;
                    
                
            
        
    

【2】测试案例

1)二叉树结构

 2)测试案例代码:

public static void main(String[] args) 
        MyBinTree head = new MyBinTree(1);

        head.left = new MyBinTree(2);
        head.right = new MyBinTree(3);

        head.left.left = new MyBinTree(4);
        head.left.right = new MyBinTree(5);
        head.right.left = new MyBinTree(6);
        head.right.right = new MyBinTree(7);

        head.left.left.left = new MyBinTree(8);
        head.left.right.right = new MyBinTree(9);
        // 先序打印
        printByPreOrder(head);
        System.out.println();

        // 中序打印
        printByInOrder(head);
        System.out.println();

        // 后序打印
        printByPostOrder(head);
    

3)打印结果:

先序遍历:1 2 4 8 NULL NULL NULL 5 NULL 9 NULL NULL 3 6 NULL NULL 7 NULL NULL 
中序遍历:NULL 8 NULL 4 NULL 2 NULL 5 NULL 9 NULL 1 NULL 6 NULL 3 NULL 7 NULL 
后序遍历:NULL NULL 8 NULL 4 NULL NULL NULL 9 5 2 NULL NULL 6 NULL NULL 7 3 1

以上是关于java迭代实现二叉树先中后序遍历(非递归)的主要内容,如果未能解决你的问题,请参考以下文章

二叉树先中后序遍历(递归非递归)

二叉树先中后序遍历(递归非递归)

二叉树:前中后序迭代方式的写法就不能统一一下么?

C语言数据结构,急求在线二叉树先序中序后序递归遍历

一个套路,写出来二叉树的迭代遍历

二叉树的先中后序遍历-JS非递归实现