java数据结构与算法之使用非递归的方式进行二叉树的前序后序中序遍历

  • 使用非递归遍历二叉树
    下列代码是绕二叉树一圈
    去是,前序遍历,回是中序遍历
    在这里插入图片描述
package com.luas.tree;

import java.util.LinkedList;

/**
 * 使用while循环去走完一圈二叉树,使用栈来存储走过的路
 *
 * @author by FZB
 * @date 2023/8/4
 */
public class TreeTraversal01 {

    public static void main(String[] args) {
        TreeNode root = new TreeNode(new TreeNode(new TreeNode(4), 2, null),
                1,
                new TreeNode(new TreeNode(5), 3, new TreeNode(6)));


        //1.使用栈来记录走过的路,以便左节点遍历到头时可以返回
        LinkedList<TreeNode> linkedList = new LinkedList<>();
        //2.使用while循环先去走完左子树
        TreeNode current = new TreeNode();
        //3.首先将当前节点记录根节点的值
        current = root;
        //4.当当前节点不为null时表示左边还没有走到头,或者当栈不为空时,去原路回
        while (current != null||!linkedList.isEmpty()) {
            if (current != null) {
                //5.每次将当前节点压入栈
                linkedList.push(current);
                System.out.println("去:" + current.val);
                current = current.left;
            } else {//6.当遍历到头时,出栈,原路返回,此时会发现,while循环根本进入不到else中的代码,所以需要加上||linkedList!=null
                TreeNode pop = linkedList.pop();
                System.out.println("回:"+pop.val);
                //当栈中空了时就将根节点右节点的赋给当前节点,此时又会去执行if里面的语句且只将一个节点压入栈内,当走到头时,又会去赋值给右节点
                current = pop.right;
            }

        }


    }

}

非递归代码,去时打印是前序遍历,回时打印时中序遍历

  • 使用非递归完成后序遍历
    后序遍历时,需要判断什么时候才能出栈,因为后序遍历的顺序,是左右值,当右节点为null或者右节点处理完成时,才能进行弹出栈,那么什么时候右节点处理完成呢,就是当上一次弹出的元素为当前节点的右节点时,说明右节点处理完成,当前节点可以出栈
package com.luas.tree;

import java.util.LinkedList;

/**
 * 二叉树的后序遍历
 * 左右值
 * @author by FZB
 * @date 2023/8/8
 */
public class TreeTraversal02 {
    public static void main(String[] args) {
        TreeNode root = new TreeNode(new TreeNode(new TreeNode(4), 2, new TreeNode(7)),
                1,
                new TreeNode(new TreeNode(5), 3, new TreeNode(6)));

        //使用栈来记录走过的路
        LinkedList<TreeNode> stack = new LinkedList<>();
        TreeNode current = root;
        TreeNode pop = null;
        while(current != null || !stack.isEmpty()){
            if(current != null){
                //去的时候,为了记录,将去的时候的路径放在栈里面
                stack.push(current);
                //System.out.println("去"+current.val);
                current = current.left;
            }else{
                //当栈中不为空时,会来的时候从栈里面弹出来
                //右子树处理完成才去弹出,一两种情况,一种是右子树为null
                TreeNode peek = stack.peek();
                //判断弹出节点的是是否是右节点,如果弹出的不是右节点说明右节点还没处理完成,此时还不能弹出
                if(peek.right == null || peek.right == pop){
                     pop = stack.pop();
                    //将弹出右节点的赋给当前节点
                    System.err.println("回"+pop.val);
                }else{
                    current = peek.right;
                }


            }
        }

    }




}
  • 使用非递归完成前序中序后序遍历
package com.luas.tree;

import java.util.LinkedList;

/**
 * 前序后序中序遍历通用模板
 *
 * 前序是  值 左 右
 * 中序是  左 值 右
 * 后序是  左 右 值
 *
 * @author by FZB
 * @date 2023/8/8
 */
public class GlobalTraversal {



        public static void main(String[] args) {
            TreeNode root = new TreeNode(new TreeNode(new TreeNode(4), 2, new TreeNode(7)),
                    1,
                    new TreeNode(new TreeNode(5), 3, new TreeNode(6)));
            //使用栈来记录走过的路
            LinkedList<TreeNode> stack = new LinkedList<>();
            TreeNode current = root;
            TreeNode pop = null;
            while (current != null || !stack.isEmpty()) {

                if (current != null) {
                    stack.push(current);
                    System.out.println("前序遍历:"+ current.val);
                    current = current.left;

                } else {
                    TreeNode peek = stack.peek();
                    //  没有右子树
                    if (peek.right == null) {
                        pop = stack.pop();
                        System.out.println("中序遍历:"+peek.val);
                        System.out.println("后序遍历:"+pop.val);
                        //   右子树处理完成
                    } else if (peek.right == pop) {
                        pop = stack.pop();
                        System.out.println("后序遍历:"+pop.val);
                        //   待处理右子树
                    } else {
                        System.out.println("中序遍历:"+peek.val);
                        current = peek.right;

                    }


                }
            }

        }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值