【数据结构——树】二叉树的遍历(前序、中序、后序、层序)迭代+递归

文章目录

    • 二叉树的定义
    • 二叉树的遍历方式
      • 前序遍历
        • 递归DFS
        • 迭代(栈)
      • 中序遍历
        • 递归DFS
        • 迭代(栈)
      • 后序遍历
        • 递归DFS
        • 迭代(栈)
      • 层序遍历
        • 迭代(队列)

二叉树的定义

二叉树是一种常见的树状数据结构,它由一个称为根节点(Root)的节点和最多两个指向其他节点的指针(左子节点和右子节点)组成。

    static class TreeNode{public char val;//节点值public TreeNode left;//左孩子节点public TreeNode right;//右孩子节点public TreeNode(char val){//节点赋值this.val = val;}public TreeNode(char val,TreeNode left,TreeNode right){//节点赋值的同时,指定左右孩子this.val = val;this.left =left;this.right =right;}}

二叉树的遍历方式

  • 创建二叉树:
    public static TreeNode creatTree(){TreeNode A = new TreeNode('A');TreeNode B = new TreeNode('B');TreeNode C = new TreeNode('C');TreeNode D = new TreeNode('D');TreeNode E = new TreeNode('E');TreeNode F = new TreeNode('F');TreeNode G = new TreeNode('G');TreeNode H = new TreeNode('H');A.left = B;A.right = C;B.left = D;B.right = E;C.left = F;C.right = G;E.right = H;return A;}

图示为:
在这里插入图片描述

前序遍历

前序遍历(根左右) A B D E H C F G

递归DFS

 //全局list集合 //存放树的节点static List<TreeNode> list = new ArrayList<>();// dfs  深度优先递归private static void dfs(TreeNode root) {if(root == null) return;//用于判空,也做为递归出口list.add(root);//根dfs(root.left);//左dfs(root.right);//右}

迭代(栈)

方式一

 //全局list集合 //存放树的节点static List<TreeNode> list = new ArrayList<>();/*** 迭代法 1 + 栈* 前序遍历是根左右,首先保存根节点,然后出栈,然后将值入list。* 然后入右节点、入左节点再重新进行循环,* 即将左节点当做根节点进行操作(即操作左子树),操作完左子树之后再操作右子树。*/private static void iteration1(TreeNode root) {if (root == null) return;Deque<TreeNode> stack= new LinkedList<>();stack.push(root);// 将根节点入栈while(!stack.isEmpty()){root = stack.pop();//弹出遍历的节点list.add(root);// 先将右子节点入栈,再将左子节点入栈,这样出栈时就会先访问左子节点if(root.right != null) stack.push(root.right);if(root.left != null) stack.push(root.left);}}

方式二(推荐)

//全局list集合 //存放树的节点static List<TreeNode> list = new ArrayList<>();/*** 迭代法  2  + 栈* 入根然后一直入左,直到没有左,然后出栈顶(找到最左的节点),* 再然后找到最左的节点的右孩子,此时右孩子为根节点。然后循环操作。* 要点:根节点、左节点处理完之后,把右节点当做根节点然后又从循环开头开始操作(即整理整个右子树)。*/private static void iteration(TreeNode root) {if (root == null) return;Deque<TreeNode> stack= new LinkedList<>();while(!stack.isEmpty() || root != null){while(root != null){  // 左节点一直入栈同时加入到listlist.add(root);stack.push(root);root = root.left;}root = stack.pop();root = root.right;//切换右节点继续循环}}

中序遍历

中序遍历(左根右) D B E H A F C G

递归DFS

	//全局list集合 //存放树的节点static List<TreeNode> list = new ArrayList<>();/*** dfs 递归 中序遍历**/private static void dfs(TreeNode root) {if(root == null) return;dfs(root.left);list.add(root);dfs(root.right);}

迭代(栈)

方式一

	//全局list集合 //存放树的节点static List<TreeNode> list = new ArrayList<>();/*** 迭代方式一 +栈*/private static void iteration(TreeNode root) {if (root == null) return;Deque<TreeNode> stack = new LinkedList<>();while(!stack.isEmpty() || root != null){//注意  栈可能为空 此时root的左子树都遍历完了  继续遍历root.right  所以要加条件root != nullif (root != null) { // 指针来访问节点,访问到最底层stack.push(root);// 将访问的节点放进栈root = root.left; // 左}else {root = stack.pop();list.add(root); // 中root = root.right; // 右}}

方式二(推荐)

	//全局list集合 //存放树的节点static List<TreeNode> list = new ArrayList<>();/*** 迭代方式二 +栈*/private static void iteration1(TreeNode root) {if (root == null) return;Deque<TreeNode> stack = new LinkedList<>();while(!stack.isEmpty() || root != null) {//注意  栈可能为空 此时root的左子树都遍历完了  继续遍历root.right  所以要加条件root != nullwhile(root != null){stack.push(root);root = root.left;//访问左子树节点到最底层}root = stack.pop();//若节点左子树为null 则弹出 加入listlist.add(root);root = root.right;//接着访问弹出节点的左子树}}

后序遍历

后序遍历(左右根) D H E B F G C A

递归DFS

//全局list集合 //存放树的节点static List<TreeNode> list = new ArrayList<>();/*** dfs 后序递归(左右根)  D  H   E   B   F   G   C   A*/private static void dfs(TreeNode root) {if(root == null) return;dfs(root.left);//左dfs(root.right);//右list.add(root);//根}

迭代(栈)

方式一

//全局list集合 //存放树的节点static List<TreeNode> list = new ArrayList<>();/*** 迭代方式一 + 栈 (在前序遍历上改良  交换前序遍历的左右孩子入栈的顺序  得到  根右左  然后再逆转过来就是后序遍历*/private static void iteration1(TreeNode root) {if(root == null) return;Deque<TreeNode> stack = new LinkedList<>();stack.push(root);while(!stack.isEmpty() ){root = stack.pop();list.add(root);if(root.left != null) stack.push(root.left);//相对于前序遍历,这更改一下入栈顺序  使得右节点率先出栈  (根右左--->左右根)if(root.right != null) stack.push(root.right);}//上面得到的其实就是后序遍历的逆序   所以只要把list逆过来就是后序遍历了 (根右左--->左右根)Collections.reverse(list);}

方式二(推荐)

 /*** 迭代方式二 + 栈* 中左一直入栈,直到没有左边,然后查找栈顶节点是否有右节点,没有则出栈入vector,* 有则将右节点作为根节点重新循环(即将右边那部分直接当做一棵树)。*/private static void iteration(TreeNode root) {if (root == null) {return ;}Stack<TreeNode> stack = new Stack<>();TreeNode prev = null;while (root != null || !stack.isEmpty()) {while (root != null) {stack.push(root);root = root.left;}TreeNode peekNode = stack.peek();if (peekNode.right != null &&  peekNode.right!= prev) {// 如果右子节点存在且未被访问过,则处理右子树root = peekNode.right;} else {// 否则,说明左右子树都已经处理完毕,可以访问当前节点list.add(peekNode);prev = stack.pop();//记录弹出的节点  用于判断下次处理节点时  右孩子节点是否处理过}}}

层序遍历

层序遍历 A B C D E F G H

迭代(队列)

/*** 迭代 + 队列* @param root*/private static void iteration(TreeNode root) {if(root == null) return;Queue<TreeNode> queue = new LinkedList<>();//队列queue.offer(root);while(!queue.isEmpty()){int size = queue.size();//记录每层的节点个数for (int i = 0; i < size; i++) {//取出每层的节点root = queue.poll();list.add(root);if(root.left != null) queue.offer(root.left);//如果当前节点的孩子节点不为空则加入if(root.right != null) queue.offer(root.right);}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/120679.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java“牵手”京东商品评论数据接口方法,京东商品评论接口,京东商品评价接口,行业数据监测,京东API实现批量商品评论内容数据抓取示例

京东平台商品评论数据接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取京东商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片、评论内容、评论日期、评论图片、追评内容等详细信息 。 获取商品评论接口API是一种用于获取…

【Hello Algorithm】二叉树相关算法

本篇博客介绍&#xff1a;介绍二叉树的相关算法 二叉树相关算法 二叉树结构遍历二叉树递归序二叉树的交集非递归方式实现二叉树遍历二叉树的层序遍历 二叉树难题二叉树的序列化和反序列化lc431求二叉树最宽的层二叉树的后继节点谷歌面试题 二叉树结构 如果对于二叉树的结构还有…

K8s 持久化存储有几种方式?一文了解本地盘/CSI 外接存储/K8s 原生存储的优缺点

当今云原生环境中&#xff0c;Kubernetes&#xff08;K8s&#xff09;已成为既定的容器编排工具。随着 K8s 的普及&#xff0c;存储也成为 K8s 用户关注的一个重要问题&#xff1a;为了满足不同的场景需求&#xff0c;K8s 可以支持基于不同架构的多种存储方案。这些方案间有什么…

Windows——安装 Microsoft 便签

打开 Microsoft Store。 搜索 Microsoft 便签&#xff0c;点击安装。

git co 命令是什么意思,用法是怎么样的

偶然看到同事使用 git co feat/xxx 来操作 git&#xff0c;以为 co 是什么 git 新命令&#xff0c;看起来很牛逼&#xff0c;所以问了下 chatgpt&#xff0c;chatgpt 的回答如下&#xff1a; git co 是 git checkout 的缩写形式&#xff0c;需要在Git的全局配置或别名配置中启用…

AJAX学习笔记3练习

AJAX学习笔记2发送Post请求_biubiubiu0706的博客-CSDN博客 1.验证用户名是否可用 需求,用户输入用户名,失去焦点-->onblur失去焦点事件,发送AJAX POST请求,验证用户名是否可用 新建表 前端页面 WEB-INF下新建lib包引入依赖,要用JDBC 后端代码 package com.web;import jav…

线性代数的学习和整理17:向量空间的基,自然基,基变换等(未完成)

目录 3 向量空间的基&#xff1a;矩阵的基础/轴 3.1 从颜色RGB说起 3.2 附属知识 3.3 什么样的向量可以做基&#xff1f; 3.4 基的分类 3.1.1 不同空间的基---向量组的数量可能不同 3.1.2 自然基 3.1.3 正交基 3.1.4 标准正交基 3.1.5 基和向量/矩阵 3.1.6 基变换 …

React笔记(八)Redux

一、安装和配置 React 官方并没有提供对应的状态机插件&#xff0c;因此&#xff0c;我们需要下载第三方的状态机插件 —— Redux。 1、下载Redux 在终端中定位到项目根目录&#xff0c;然后执行以下命令下载 Redux npm i redux 2、创建配置文件 在 React 中&#xff0c;…

【python】可视化

柱状图 matplotlib之pyplot模块之柱状图&#xff08;bar()&#xff1a;基础参数、外观参数&#xff09;_plt.bar_mighty13的博客-CSDN博客 bar()的基础参数如下&#xff1a; x&#xff1a;柱子在x轴上的坐标。浮点数或类数组结构。注意x可以为字符串数组&#xff01; height&…

计算机毕业设计 社区买菜系统 Vue+SpringBoot+MySQL

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;Java全栈软件工程师一枚&#xff0c;来自浙江宁波&#xff0c;负责开发管理公司OA项目&#xff0c;专注软件前后端开发、系统定制、远程技术指导。CSDN学院、蓝桥云课认证讲师&#xff0c;全栈领域优质创作者。 项目内容…

【深度学习实验】NumPy的简单用法

目录 一、NumPy介绍 1. 官网 2. 官方教程 二、实验内容 1. 导入numpy库 2. 打印版本号 3. arange 函数 4. array函数 5. reshape函数 6. 矩阵点乘&#xff08;逐元素相乘&#xff09; 7. 矩阵乘法 一、NumPy介绍 NumPy是一个常用于科学计算的Python库&#xff0c;尤…

手写一个简单爬虫--手刃豆瓣top250排行榜

#拿到页面面源代码 request #通过re来提取想要的有效信息 re import requests import re url"https://movie.douban.com/top250"headers{"user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/11…

【Vue3 知识第四讲】数据双向绑定、事件绑定、事件修饰符详解

文章目录 一、数据双向绑定二、事件绑定详解2.1 **Vue中的事件绑定指令**2.2 **事件函数的调用方式**2.3 **事件函数参数传递** 三、事件修饰符3.1 **Vue中常用的事件修饰符**3.2 **按键修饰符** 四、属性绑定五、类与样式的绑定5.1 class 类的绑定5.2 style 样式绑定 一、数据…

泛型的学习

泛型深入 泛型&#xff1a;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查 泛型的格式&#xff1a;<数据类型> 注意&#xff1a;泛型只能支持引用数据类型 //没有泛型的时候&#xff0c;集合如何存储数据//如果我们没有给集合指定类型&#xff0c;默认认为…

VMWare vsphere配置虚拟机规则实例

在虚拟化平台&#xff0c;存在HA关系的虚拟机通常要求不能放置在同一物理机上以提升安全性&#xff0c;高业务互访问的虚拟机则需要放置在同一物理机上以提升性能&#xff0c;同一资源类型为高负荷的虚拟机需分散放置以平衡集群主机性能提升虚拟机效率&#xff0c;这些情况下就…

Pycharm配置及使用Git教程

文章目录 1. 安装PyCharm2. 安装Git3. 在PyCharm中配置Git插件4. 连接远程Gtilab仓库5. Clone项目代码6. 将本地文件提交到远程仓库6.1 git add6.2 git commit6.3 git push6.4 git pull 平时习惯在windows下开发&#xff0c;但是我们又需要实时将远方仓库的代码clone到本地&…

SpringMVC:从入门到精通

一、SpringMVC是什么 SpringMVC是Spring提供的一个强大而灵活的web框架&#xff0c;借助于注解&#xff0c;Spring MVC提供了几乎是POJO的开发模式【POJO是指简单Java对象&#xff08;Plain Old Java Objects、pure old java object 或者 plain ordinary java object&#xff0…

zookeeper教程

zookeeper教程 zookeeper简介zookeeper的特点及数据模型zookeeper下载安装zookeeper客户端命令zookeeper配置文件zookeeper服务器常用命令zookeeper可视化管理工具zkuizookeeper集群环境搭建zookeeper选举机制使用Java原生api操作zookeeper使用java zkclient库操作zookeeper使用…

文件上传漏洞-upload靶场5-12关

文件上传漏洞-upload靶场5-12关通关笔记&#xff08;windows环境漏洞&#xff09; 简介 ​ 在前两篇文章中&#xff0c;已经说了分析上传漏的思路&#xff0c;在本篇文章中&#xff0c;将带领大家熟悉winodws系统存在的一些上传漏洞。 upload 第五关 &#xff08;大小写绕过…

C#面试十问

1&#xff1a;C#中变量类型分为哪两种&#xff1f;它们的区别是什么&#xff1f;2&#xff1a;Class和Struct的区别&#xff1f;3&#xff1a;C#中类的修饰符和类成员的修饰符有哪些&#xff1f;4&#xff1a;面向对象的三个特征&#xff08;特点&#xff09;是什么&#xff1f…