IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 二叉树的前序中序后序遍历 -> 正文阅读

[数据结构与算法]二叉树的前序中序后序遍历

分为递归和循环两种方式:

循环为模拟递归的入栈出栈的操作过程。

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Solution5_2 {


    public class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode() {}
        public TreeNode(int val) { this.val = val; }
        public TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    public List<Integer> preorderTraversal(TreeNode root) {
        if (root == null){
            return new ArrayList<>();
        }
        List<Integer> list = new ArrayList<>();
        list.add(root.val);
        List<Integer> list1 = preorderTraversal(root.left);
        list.addAll(list1);
        List<Integer> list2 = preorderTraversal(root.right);
        list.addAll(list2);
        return list;
    }

    public List<Integer> r = new ArrayList<>();
    public List<Integer> preorderTraversal2(TreeNode root) {
        preorder(root);
        return r;
    }

    //返回值为void
    public void preorder(TreeNode root) {
        if (root == null){
            return;
        }
        r.add(root.val);
        preorder(root.left);
        preorder(root.right);
    }


    public List<Integer> inorderTraversal(TreeNode root) {
        if (root == null){
            return new ArrayList<Integer>();
        }
        List<Integer> list1 = inorderTraversal(root.left);
        List<Integer> list = new ArrayList<>();
        list.addAll(list1);
        list.add(root.val);
        List<Integer> list2 = inorderTraversal(root.right);
        list.addAll(list2);
        return list;
    }

    public List<Integer> inorderTraversal2(TreeNode root) {
        inorder(root);
        return r;
    }

    public void inorder(TreeNode root){
        if (root == null){
            return;
        }
        inorder(root.left);
        r.add(root.val);
        inorder(root.right);
    }

    public List<Integer> postorderTraversal(TreeNode root) {
        if (root == null){
            return new ArrayList<>();
        }
        List<Integer> list1 = postorderTraversal(root.left);
        List<Integer> list2 = postorderTraversal(root.right);
        List<Integer> list = new ArrayList<>();
        list.addAll(list1);
        list.addAll(list2);
        list.add(root.val);
        return list;
    }


    /**
     * 思路:
     * 模拟递归方法的入栈出栈的过程
     *
     * 栈帧中元素
     * 1.结点
     * 2.结点的状态
     *
     * 过程:
     * 1.将该结点入栈(此时该结点为栈顶)
     * 2.打印该结点
     * 3.左子树入栈出栈,直到左子树完毕,该结点为栈顶
     * 4.右子树入栈出栈,直到右子树完毕,该结点为栈顶
     * 5.该结点出栈
     * 6.循环1到5,直到栈为空
     * @return
     */
    public class StackFrame {
        public TreeNode node;
        /**
         * 首次入栈,状态为1(该元素为栈顶)
         * 左子树遍历完,状态为2(该元素为栈顶)
         * 右子树遍历完,状态为3(该元素为栈顶)
         */
        public int state;

        public StackFrame(TreeNode node, int state) {
            this.node = node;
            this.state = state;
        }
    }
    public List<Integer> preorderTraversal_foreach(TreeNode root) {
        List<Integer> r = new ArrayList<>();
        if (root == null){
            return r;
        }
        //首先创建栈,用于模拟递归入栈出栈的过程
        Stack<StackFrame> stack = new Stack<>();
        TreeNode p = root;
        //将最小树不停的循环
        while (true){
            //将该元素入栈,一路向左
            while (p != null){
                //先入栈,再打印
                stack.push(new StackFrame(p, 1));
                r.add(p.val);
                p = p.left;
            }

            // 再次回来时,状态要变成2,
            // 但是同一个结点,有三次为栈顶元素,只有当前元素的状态为1,才可以变成2,状态为3时,不可以修改为2
            if (stack.peek().state == 1){
                stack.peek().state = 2;
                //开始遍历右侧
                p = stack.peek().node.right;
                continue;
            }

            //右侧遍历结束
            if (stack.peek().state == 2){
                stack.peek().state = 3;
                stack.pop();
                if (stack.isEmpty()){
                    break;
                }
            }
        }
        return r;
    }

    /**
     * 思路:
     * 1.入栈,打印,状态为1
     * 2.如果状态为2,则出栈
     * 3.否则,将状态改为2,并且将结点改为当前结点的右子结点
     * @param root
     * @return
     */
    public List<Integer> preorderTraversal_foreach2(TreeNode root) {
        List<Integer> r = new ArrayList<>();
        Stack<StackFrame> stack = new Stack<>();
        TreeNode p = root;
        while (true){
            while (p != null){
                stack.push(new StackFrame(p, 1));
                r.add(p.val);
                p = p.left;
            }

            //第三次回来时,状态由2->3,并且弹出栈
            while (!stack.isEmpty() && stack.peek().state == 2){
                stack.peek().state = 3;
                stack.pop();
            }

            if (stack.isEmpty()){
                break;
            }

            stack.peek().state = 2;
            p = stack.peek().node.right;
        }
        return r;
    }


    public List<Integer> inorderTraversal_foreach(TreeNode root) {
        List<Integer> r = new ArrayList<>();
        if (root == null){
            return r;
        }
        //首先创建栈,用于模拟递归入栈出栈的过程
        Stack<StackFrame> stack = new Stack<>();
        TreeNode p = root;
        //将最小树不停的循环
        while (true){
            //将该元素入栈,一路向左
            while (p != null){
                //先入栈,再打印
                stack.push(new StackFrame(p, 1));
                p = p.left;
            }

            // 再次回来时,状态要变成2,
            // 但是同一个结点,有三次为栈顶元素,只有当前元素的状态为1,才可以变成2,状态为3时,不可以修改为2
            if (stack.peek().state == 1){
                stack.peek().state = 2;
                r.add(stack.peek().node.val);
                //开始遍历右侧
                p = stack.peek().node.right;
                continue;
            }

            //右侧遍历结束
            if (stack.peek().state == 2){
                stack.peek().state = 3;
                stack.pop();
                if (stack.isEmpty()){
                    break;
                }
            }
        }
        return r;
    }

    public List<Integer> inorderTraversal_foreach2(TreeNode root) {
        List<Integer> r = new ArrayList<>();
        Stack<StackFrame> stack = new Stack<>();
        TreeNode p = root;
        while (true){
            while (p != null){
                stack.push(new StackFrame(p, 1));
                p = p.left;
            }

            //第三次回来时,状态由2->3,并且弹出栈
            while (!stack.isEmpty() && stack.peek().state == 2){
                stack.peek().state = 3;
                stack.pop();
            }

            if (stack.isEmpty()){
                break;
            }

            stack.peek().state = 2;
            r.add(stack.peek().node.val);
            p = stack.peek().node.right;
        }
        return r;
    }

    public static void main(String[] args) {
        new Solution5_2().test();
    }

    public void test(){
        TreeNode root = new TreeNode(1);
        TreeNode rootr = new TreeNode(2);
        TreeNode rootrl = new TreeNode(3);
        root.right = rootr;
        rootr.left = rootrl;
        List<Integer> list = preorderTraversal_foreach(root);
        System.out.println(list);
    }

}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 00:18:38  更:2021-07-28 00:19:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 19:27:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码