(数据结构)二叉树

8.二叉树

8.1概述

        二叉树是一种基本的非线性数据结构,它是由n(n>=0)个节点构成的有限集合。在二叉树中,每个节点最多有两个子节点,通常被称作左孩子(left child)和右孩子(right child)。此外,二叉树还具有以下特点: 每个节点包含一个值(也可以包含其他信息)。 有一个被称为根(root)的特殊节点,它是二叉树的起点,没有父节点。 如果一个节点存在左子节点,则该节点称为左子节点的父节点;同样,如果存在右子节点,则称为右子节点的父节点。 每个节点的所有子孙(包括子节点、孙子节点等)构成了该节点的子树(subtree)。 左子树和右子树本身也是二叉树,且可以为空。

 8.2 二叉树遍历

 遍历:

        广度优先遍历(Breadth-First Search, BFS)和深度优先遍历(Depth-First Search, DFS)是两种在图或树这类非线性数据结构中搜索节点的常用策略。

        广度优先遍历(BFS): 从根节点开始,首先访问所有与根节点直接相连的节点(即第一层邻居节点),然后按顺序访问它们的子节点(第二层),接着是孙子节点(第三层),以此类推。 使用队列作为辅助数据结构,将起始节点入队,每次从队列头部取出一个节点进行访问,并将其未被访问过的相邻节点全部加入队列尾部,直到队列为空为止。 在二叉树场景下,BFS通常实现为层序遍历,它会按照从上到下、从左到右的顺序依次访问各个节点。

        深度优先遍历(DFS): 从根节点开始,尽可能深地探索图或树的分支,直到到达叶子节点或者无法继续深入时返回上一层节点,再尝试探索其他分支。 深度优先遍历有多种方式:前序遍历(先访问根节点,再遍历左子树,最后遍历右子树)、中序遍历(先遍历左子树,再访问根节点,最后遍历右子树)、后序遍历(先遍历左子树,再遍历右子树,最后访问根节点)以及反向的前后序遍历等。 在二叉树的DFS中,通常使用递归的方式实现。另外,也可以借助栈这一数据结构,模拟递归过程进行非递归实现。 总结来说,BFS保证了同一层次的节点会被一起访问到,而DFS则是沿着一条路径尽可能深地探索,直至无法继续前进时回溯至另一条路径。这两种遍历方式在解决不同的问题时各有优势,如寻找最短路径、拓扑排序等场景常常会用到BFS,而解决迷宫求解、判断连通性等问题时DFS则更为常见。

 8.3 深度优先遍历

深度优先遍历(DFS)分为:

        前序遍历(Preorder Traversal): 在前序遍历中,访问顺序为:根节点 -> 左子树 -> 右子树。 递归地对当前节点的左子树进行前序遍历。 递归地对当前节点的右子树进行前序遍历。

        中序遍历(Inorder Traversal): 在中序遍历中,访问顺序为:左子树 -> 根节点 -> 右子树。 递归地对当前节点的左子树进行中序遍历。 访问当前节点。 递归地对当前节点的右子树进行中序遍历。

        后序遍历(Postorder Traversal): 在后序遍历中,访问顺序为:左子树 -> 右子树 -> 根节点。 递归地对当前节点的左子树进行后序遍历。 递归地对当前节点的右子树进行后序遍历。 访问当前节点。

8.3.1 递归实现遍历


public class TreeTraversal {public static void main(String[] args) {TreeNode tree = new TreeNode(new TreeNode(new TreeNode(4), 2, null),1,new TreeNode(new TreeNode(5), 3, new TreeNode(6)));preOrder(tree);System.out.println();inOrder(tree);System.out.println();postOrder(tree);System.out.println();
}/** 前序遍历 根节点=》左子树=》右子树* *///递归实现static void preOrder(TreeNode treeNode){if(treeNode==null){return;}System.out.print(treeNode.val+"\t");//根节点preOrder(treeNode.left);//左子树preOrder(treeNode.right);//右子树}/** 中序遍历 左子树=》=》根节点=》右子树* */static void inOrder(TreeNode treeNode){if(treeNode==null){return;}inOrder(treeNode.left);//左子树System.out.print(treeNode.val+"\t");//根节点inOrder(treeNode.right);//右子树}/** 后序遍历 左子树=》右子树 =》根节点* */static void postOrder(TreeNode treeNode){if(treeNode==null){return;}postOrder(treeNode.left);//左子树postOrder(treeNode.right);//右子树System.out.print(treeNode.val+"\t");//根节点}
}

8.3.2 非递归实现遍历

//非递归实现
public class TreeTraversal2 {public static void main(String[] args) {TreeNode tree = new TreeNode(new TreeNode(new TreeNode(4), 2, null),1,new TreeNode(new TreeNode(5), 3, new TreeNode(6)));preOrder(tree);System.out.println();inOrder(tree);System.out.println();postOrder(tree);System.out.println();}/** 前序遍历 根节点=》左子树=》右子树* */static void preOrder(TreeNode treeNode){LinkedList<TreeNode> stack = new LinkedList<>();//定义一个指针,当前节点TreeNode curr = treeNode;//去的路径为前序遍历,回的路径为中序遍历while (curr != null||!stack.isEmpty()) {if (curr != null) {stack.push(curr);//压入栈,为了记住返回的路径System.out.print("前序" + curr.val + "\t");curr = curr.left;}else {TreeNode peek = stack.peek();TreeNode pop=stack.pop();curr= pop.right;}}}/** 中序遍历 左子树=》=》根节点=》右子树* */static void inOrder(TreeNode treeNode){LinkedList<TreeNode> stack = new LinkedList<>();//定义一个指针,当前节点TreeNode curr = treeNode;//去的路径为前序遍历,回的路径为中序遍历while (curr != null||!stack.isEmpty()) {if (curr != null) {stack.push(curr);//压入栈,为了记住返回的路径curr = curr.left;}else {TreeNode peek = stack.peek();TreeNode pop=stack.pop();System.out.print("中序" + pop.val + "\t");curr= pop.right;}}}/** 后序遍历 左子树=》右子树 =》根节点* */static void postOrder(TreeNode treeNode){LinkedList<TreeNode> stack = new LinkedList<>();//定义一个指针,当前节点TreeNode curr = treeNode;//去的路径为前序遍历,回的路径为中序遍历TreeNode pop = null;while (curr != null || !stack.isEmpty()) {if (curr != null) {stack.push(curr);//压入栈,为了记住返回的路径curr = curr.left;} else {TreeNode peek = stack.peek();//右子树为null,或者最近一次弹栈的元素与当前元素的右子树相等 说明全部子树都处理完了if (peek.right == null||peek.right==pop) {//最近一次弹栈的元素pop= stack.pop();System.out.print("后序" + pop.val + "\t");} else {curr = peek.right;}}}}
}

8.3.2 非递归实现遍历2


//非递归实现
public class TreeTraversal3 {public static void main(String[] args) {TreeNode tree = new TreeNode(new TreeNode(new TreeNode(4), 2, null),1,new TreeNode(new TreeNode(5), 3, new TreeNode(6)));postOrder(tree);System.out.println();}static void postOrder(TreeNode treeNode){LinkedList<TreeNode> stack = new LinkedList<>();//定义一个指针,当前节点TreeNode curr = treeNode;//去的路径为前序遍历,回的路径为中序遍历TreeNode pop = null;while (curr != null || !stack.isEmpty()) {if (curr != null) {//压入栈,为了记住返回的路径stack.push(curr);//待处理左子树System.out.println("前序"+curr.val);curr = curr.left;} else {TreeNode peek = stack.peek();//右子树为null,无需处理if (peek.right == null) {//最近一次弹栈的元素System.out.println("中序"+peek.val);pop= stack.pop();System.out.println("后序"+pop.val);}else if(peek.right==pop) {//最近一次弹栈的元素与当前元素的右子树相等 说明右子树都处理完了pop= stack.pop();System.out.println("后序"+pop.val);}else {//待处理右子树System.out.println("中序"+peek.val);curr = peek.right;}}}}
}

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

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

相关文章

LVS负载均衡集群的基本介绍

目录 一、LVS集群基本介绍 1、什么是集群 2、集群的类型 2.1 负载均衡群集&#xff08;Load Balance Cluster) 2.2 高可用群集(High Availiablity Cluster) 2.3 高性能运算群集(High Performance Computing Cluster) 3、负载均衡集群的结构 4、LVS集群类型中的术语 5、…

【javaEE-唠嗑局】如何用jconsole观察进程里的多线程情况

&#x1f4e2;编程环境&#xff1a;idea 如何用jconsole观察进程里的多线程情况 1. 打开jdk2. 打开jconsole3. 查看每个线程的情况 以下面这段代码为例&#xff1a;代码运行时&#xff0c;包括一个进程&#xff0c;该进程中有两个线程。 package thread; public class Demo1 …

【algorithm】算法基础课---排序算法(附笔记 | 建议收藏)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;AcWing算法学习笔记 &#x1f4ac;总结&#xff1a;希望你看完…

(3)(3.2) MAVLink2数据包签名(安全)

文章目录 前言 1 配置 2 使用 3 MAVLink协议说明 前言 ArduPilot 和任务计划器能够通过使用加密密钥添加数据包签名&#xff0c;为空中 MAVLink 传输增加安全性。这并不加密数据&#xff0c;只是控制自动驾驶仪是否响应 MAVLink 命令。 当自动驾驶仪处于激活状态时&#x…

【C语言】Leetcode 206.反转链表

博主主页&#xff1a;17_Kevin-CSDN博客 收录专栏&#xff1a;《Leetcode》 题目 解决思路 思路一&#xff1a;翻转链表 struct ListNode* reverseList(struct ListNode* head) {if(head NULL){return NULL;}struct ListNode* n1 NULL,*n2 head,*n3 n2 -> next;while(…

Dell R730 2U服务器实践2:VMWare ESXi安装

缘起 刚到手边的一台Dell R730是三块硬盘raid0 &#xff0c;把我惊出一身冷汗&#xff0c;准备把它们改组成raid1 或者raid5 。 但是舍不得里面的ESXi 8 &#xff0c;寻找能否把raid0改成raid1 还不掉WSXi的方法&#xff0c;很遗憾没有找到。那样只能重装ESXi了。 ESXi软件下…

MyCAT学习——在openEuler22.03中安装MyCAT2(网盘下载版)

准备工作 因为MyCAT 2基于JDK 1.8开发。也需要在虚拟机中安装JDK&#xff08;JDK官网就能下载&#xff0c;我这提供一个捷径&#xff09; jdk-8u401-linux-x64.rpmhttps://pan.baidu.com/s/1ywcDsxYOmfZONpmH9oDjfw?pwdrhel下载对应的tar安装包,以及对应的jar包 安装程序包…

Tomcat概念、安装及相关文件介绍

目录 一、web技术 1、C/S架构与B/S架构 1.1 http协议与C/S架构 1.2 http协议与B/S架构 2、前端三大核心技术 2.1 HTML&#xff08;Hypertext Markup Language&#xff09; 2.2 css&#xff08;Cascading Style Sheets&#xff09; 2.3 JavaScript 3、同步和异步 4、…

如何使用 ArcGIS Pro 统计四川省各市道路长度

在某些时候&#xff0c;我们需要进行分区统计&#xff0c;如果挨个裁剪数据再统计&#xff0c;不仅步骤繁琐、耗时&#xff0c;还会产生一些多余的数据&#xff0c;这里教大家如何在不裁剪数据的情况下统计四川各市的道路长度&#xff0c;希望能对你有所帮助。 数据来源 教程…

苹果发布新款 MacBook Air 13/15升级M3售8999元起

苹果官网发布新款 MacBook Air&#xff0c;13 英寸和 15 英寸同时升级。 搭载 M3 芯片&#xff0c;性能更强&#xff0c;续航最长可达 18 小时&#xff0c;最多可连接两台外接显示器。 这是一次常规的芯片升级&#xff0c;外观相比上代没有变化。拥有午夜色、星光色、深空灰和银…

在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新

文章目录 一、需求背景二、token刷新的方案1、根据过期时间重新获取2、定时刷新token接口3、使用了RefreshToken 三、关于RefreshToken四、Refresh Token的优点五、Refresh Token的工作原理六、Refresh Token的使用流程七、Refresh Token的实现步骤1、登录成功后保存AccessToke…

机器人顶刊IJRR近期国人新作(2024)

一、IJRR简介 The International Journal of Robotics Research&#xff08;IJRR&#xff09;是机器人领域的高水平学术期刊&#xff0c;专注于发布关于机器人技术和相关领域的最新研究成果。IJRR创刊于1982年&#xff0c;是该领域的第一本学术刊物&#xff0c;2022-2023最新影…

销量王者!三一新能源搅拌车助力商砼运输走向低碳未来

2023年,在国家扩大内需和“双碳战略”的双重推进下,新老基建项目开工速度纷纷加快,各个行业对应用于工程基建、房地产等中短途混凝土运输的新能源搅拌车有了更大的需求量。 终端上牌数据显示,2023年1-12月新能源重卡累计销售23560辆,同比增长35.65%。其中,搅拌车销量暴涨,实销…

Kafka面经

1.Kafka如何保证消息不丢失 生产者&#xff1a; 1.Producer 默认是异步发送消息&#xff0c;这种情况下要确保消息发送成功&#xff0c;有两个方法 a. 把异步发送改成同步发送&#xff0c;这样 producer 就能实时知道消息发送的结果。 b. 添加异步回调函数来监听消息发送的结…

C++模拟揭秘刘谦魔术,领略数学的魅力

新的一年又开始了&#xff0c;大家新年好呀~。在这我想问大家一个问题&#xff0c;有没有同学看了联欢晚会上刘谦的魔术呢&#xff1f; 这个节目还挺有意思的&#xff0c;它最出彩的不是魔术本身&#xff0c;而是小尼老师“念错咒语”而导致他手里的排没有拼在一起&#xff0c;…

新手想玩硬件,买单片机还是树莓派好?

新手想玩硬件&#xff0c;买单片机还是树莓派好&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#x…

前端食堂技术周刊第 114 期:Interop 2024、TS 5.4 RC、2 月登陆浏览器的新功能、JSR、AI SDK 3.0

美味值&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f; 口味&#xff1a;凉拌鸡架 食堂技术周刊仓库地址&#xff1a;https://github.com/Geekhyt/weekly 大家好&#xff0c;我是童欧巴。欢迎来到前端食堂技术周刊&#xff0c;我们先来看下…

一本书讲透ChatGPT——理论与实践的完美结合,大模型技术工程师的必备指南

写在前面 OpenAI 在 2022 年 11 月推出了人工智能聊天应用—ChatGPT。它具有广泛的应用场景&#xff0c;在多项专业和学术基准测试中表现出的智力水平&#xff0c;不仅接近甚至有时超越了人类的平均水平。这使得 ChatGPT 在推出之初就受到广大用户的欢迎&#xff0c;被科技界誉…

Centos 9 安装 k8s

为了尽可能契合生产环境的部署情况&#xff0c;这里用kubeadm安装集群&#xff0c;同时方便跟随笔记一步步实践的过程&#xff0c;也更加了解k8s的一些特性和基础知识。 先决条件 这里将通过虚拟机安装3台centos stream 9服务器&#xff0c;并组成kubeneters集群&#xff08;…

蓝桥杯练习题——dp

五部曲&#xff08;代码随想录&#xff09; 1.确定 dp 数组以及下标含义 2.确定递推公式 3.确定 dp 数组初始化 4.确定遍历顺序 5.debug 入门题 1.斐波那契数 思路 1.f[i]&#xff1a;第 i 个数的值 2.f[i] f[i - 1] f[i - 2] 3.f[0] 0, f[1] 1 4.顺序遍历 5.记得特判 …