算法通关:017_2:二叉树及三种顺序的非递归遍历

文章目录

题目

二叉树及三种顺序的非递归遍历

思路

java 复制代码
import java.util.Stack;

/**
 * @Author: ggdpzhk
 * @CreateTime: 2024-08-04
 * 二叉树非递归版本
 */
public class _017_Tree2 {

    public static void main(String[] args) {
        TreeNode head = new TreeNode(1);
        head.left = new TreeNode(2);
        head.right = new TreeNode(3);
        head.left.left = new TreeNode(4);
        head.left.right = new TreeNode(5);
        head.right.left = new TreeNode(6);
        head.right.right = new TreeNode(7);

        System.out.println("先序遍历非递归版");
        preOrder(head);
        System.out.println();

        System.out.println("中序遍历非递归版");
        inOrder(head);
        System.out.println();

        System.out.println("后序遍历非递归版:两个栈");
        postOrder(head);
        System.out.println();

        System.out.println("后序遍历非递归版:1个栈");
        postOrder2(head);
        System.out.println();
    }


    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

    //先序打印所有节点,非递归版
    public static void preOrder(TreeNode head) {
        if(head != null){
            Stack<TreeNode> stack = new Stack<TreeNode>();
            stack.push(head);
            //压入顺序先右再左  这样弹出顺序就是反的,就是我们要的先序遍历的顺序
            //不懂你就写一遍 这个思路真的很牛
            while(!stack.isEmpty()){
                head = stack.pop();
                System.out.print(head.val + " ");
                if(head.right != null){
                    stack.push(head.right);
                }
                if(head.left != null){
                    stack.push(head.left);
                }
            }
            System.out.println();
        }
    }

    //中序打印所有节点,非递归版
    public static void inOrder(TreeNode head) {
        if(head != null){//这个是root
            Stack<TreeNode> stack = new Stack();
            //下面的这个head是相对的根节点
            while(!stack.isEmpty() || head != null){//栈不为空 或者当前子树不为空        ( 比如左边界最后一个点 子树就为空,但是栈里还有东西,就还会进whil)
                if(head != null){
                    //子树左边界全部进栈
                    stack.push(head);
                    head = head.left;
                }else{
                    //栈弹出一个节点,打印
                    //弹出节点为head,对右子树 左边界进栈
                    head = stack.pop();
                    System.out.print(head.val + " ");
                    head = head.right;
                }
            }
            System.out.println();
        }
    }
    //后序打印所有节点,非递归版
    //这是用两个栈的方法
    /*
    算法:
        先 :中 右 左(出栈才嫩实现正确顺序)
        先`:中 左 右(调换出栈顺序)
        后 :左 右 中(把 先` 出栈顺序反转),那就是 让先`进后栈再出栈
     */
    public static void postOrder(TreeNode head) {
        if(head != null){
            Stack<TreeNode> stack = new Stack();
            Stack<TreeNode> collect = new Stack();
            stack.push(head);
            while(!stack.isEmpty()){
                head = stack.pop();//出栈再进栈
                collect.push(head);//将其输出即可
                if(head.left != null){
                    stack.push(head.left);
                }
                if(head.right != null){
                    stack.push(head.right);
                }
            }
            //此时已全部进collect栈,将其输出
            while(!collect.isEmpty()){//栈嘛,输出就没了,不用++
                System.out.print(collect.pop().val+" ");
            }
        }
        System.out.println();
    }

    //后序打印所有节点,非递归版
    //这是用1个栈的方法
    //先处理左右字数,再返回网上。h是哨兵
    //                       左子树==h说明左边已经处理完,该处理右子树
    //                       右子树==h说明左右子树都处理完,往上走,回到相对的根节点
    public static void postOrder2(TreeNode h) {
        if(h != null){
            Stack<TreeNode> stack = new Stack();
            stack.push(h);
            //如果始终没有打印过节点,h就一直是root头节点
            //一旦打印过节点,h就变成打印节点
            //之后h的含义:上一次打印的节点
            while(!stack.isEmpty()){
                TreeNode cur = stack.peek();
                if(cur.left != null
                        && h != cur.left
                        && h != cur.right){
                    //有左树且左树没处理过
                    stack.push(cur.left);
                }else if(cur.right != null
                        && h != cur.right){
                    //有右树且右树没处理过
                    stack.push(cur.right);
                }else {
                    //左树,右树都没有 或者 都处理完了
                    System.out.print(cur.val+" ");
                    h = stack.pop();
                }
            }
            System.out.println();
        }
    }
}

运行结果

相关推荐
Dream it possible!2 小时前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
DevOpenClub2 小时前
职教高考控制线 API:招生类别枚举、筛选与空分数含义
java·数据库·高考
心抵鹊2 小时前
算法之双指针系列(一)
算法·leetcode
十二2 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
心祭丫丫3 小时前
【每天一个 Python 小案例17】Python 实现通讯录
开发语言·人工智能·笔记·python·学习
露天赏雪3 小时前
第3篇:Sentinel熔断降级实战:大模型接口抖动时的服务兜底方案
java·开发语言·人工智能·spring boot·spring·servlet·sentinel
小此方3 小时前
[算法实战论:动态规划]回文串问题的dp解法,回文串问题的母题,以及以此为基础的派生题
算法·动态规划
天天被压力3 小时前
【A股分钟级高频数据完全手册 #06】北交所分钟级数据接口:京市股票Pro版最新分时
java·人工智能·python
天天被压力3 小时前
【A股分钟级高频数据完全手册 #05】指数历史分钟数据接口:Pro版沪深指数分时回放
java·人工智能·python
captain3764 小时前
▲统一功能——DispatcherServlet源码分析
java·spring·java-ee·log4j·maven