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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 二叉树的先序、中序、后序遍历以及代码实现 -> 正文阅读

[数据结构与算法]二叉树的先序、中序、后序遍历以及代码实现

一、二叉树的三种遍历方式

二叉树的遍历主要有三种:先(根)序遍历(根左右),中(根)序遍历(左根右),后(根)序遍历(左右根),以下图为例分别说明。
在这里插入图片描述

1、先(根)序遍历(根左右)

先序遍历的原则是:先根、再左、再右。
即:ABCDEFGH

2、中(根)序遍历(左根右)

中序遍历的原则是:先左、再根、再右。
即:BDCEAFHG

3、后(根)序遍历(左右根)

后序遍历的原则是:先左、再右、再根。
即:DECBHGFA

二、代码实现二叉树的三种遍历方式

 /**
 * 下文中用到的TreeNode类
 */
 class TreeNode {
   int val = 0;
   TreeNode left = null;
   TreeNode right = null;
 }

1、递归方式实现

	/**
     * 先序遍历的原则是:先根、再左、再右。
     * @param root
     * @param list
     */
    private void preorder(TreeNode root, List<Integer> list){
        if(root != null){
            list.add(root.val);
            preorder(root.left,list);
            preorder(root.right,list);
        }
    }

    /**
     * 中序遍历的原则是:先左、再根、再右
     * @param root
     * @param list
     */
    private void inorder(TreeNode root, List<Integer> list){
        if(root != null){
            inorder(root.left,list);
            list.add(root.val);
            inorder(root.right,list);
        }
    }

    /**
     * 后序遍历的原则是:先左、再右、再根
     * @param root
     * @param list
     */
    private void postorder(TreeNode root, List<Integer> list){
        if(root != null){
            postorder(root.left,list);
            postorder(root.right,list);
            list.add(root.val);
        }
    }

2、迭代方式实现

    /**
     * 先序遍历的原则是:先根、再左、再右。
     * 1.辅助变量 tempNode 初始化为根节点
     * 2.当 tempNode != null 时,就保存这个节点值到 list 中,然后将其入栈并置 tempNode为它自己的左子节点
     * 3.当 tempNode == null 时,说明已经遍历到二叉树的左下节点了,这时前序遍历应该遍历右子树了,首先 pop 出已经遍历保存过的父节点,然后置 tempNode 为 pop 出的父节点的右子节点
     * @param root
     * @param list
     */
    private void preorder(TreeNode root, List<Integer> list){
        Stack<TreeNode> stack = new Stack<>();
        TreeNode tempNode = root;
        while(!stack.isEmpty() || tempNode != null){
            if (tempNode != null) {
                list.add(tempNode.val);
                stack.push(tempNode);
                tempNode = tempNode.left;
            } else {
                tempNode = stack.pop();
                tempNode = tempNode.right;
            }
        }
    }

    /**
     * 中序遍历的原则是:先左、再根、再右
     * 1.辅助变量 tempNode 初始化 root
     * 3.当栈非空或 tempNode 非 null 时,循环
     *  3.1 tempNode != null 时,说明还有左子节点存在,将 tempNode 入栈,并且将 tempNode 置为它自己的左子节点
     *  (和前序遍历的区别在于这里遍历到先不保存到 list 中,出栈的时候再将其保存到 list 中)
     *  3.2 tempNode == null 时,说明到二叉树左下的节点了,这时栈顶的父节点出栈赋值给 tempNode ,并保存节点值到 list ,将 tempNode 置为栈顶节点的右子节点继续循环
     * @param root
     * @param list
     */
    private void inorder(TreeNode root, List<Integer> list){
        Stack<TreeNode> stack = new Stack<>();
        TreeNode tempNode = root;
        while(!stack.isEmpty() || tempNode != null){
            if (tempNode != null) {
                stack.push(tempNode);
                tempNode = tempNode.left;
            } else {
                tempNode = stack.pop();
                list.add(tempNode.val);
                tempNode = tempNode.right;
            }
        }
    }

    /**
     * 后序遍历的原则是:先左、再右、再根
     * 1.对应前序遍历的反操作:
     * 2.前序遍历从尾部添加元素,后序遍历从头部添加元素
     * 3.前序遍历去左子树,后序遍历去右子树
     * @param root
     * @param list
     */
    private void postorder(TreeNode root, List<Integer> list){
        Stack<TreeNode> stack = new Stack<>();
        TreeNode tempNode = root;
        while (!stack.isEmpty() || tempNode != null) {
            if (tempNode != null) {
                stack.push(tempNode);
                list.add(0, tempNode.val);
                tempNode = tempNode.right;
            } else {
                tempNode = stack.pop();
                tempNode = tempNode.left;
            }
        }
    }
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-12 16:37:25  更:2022-05-12 16:38:02 
 
开发: 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年11日历 -2024/11/26 3:40:17-

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