2025春新生培训数据结构(树,图)

教学目标:

1,清楚什么是树和图,了解基本概念,并且理解其应用场景

2,掌握一种建图(树)方法

3,掌握图的dfs和树的前中后序遍历

例题与习题

2025NENU新生培训(树,图)习题

引言

恭喜各位!当你学到图和树的内容的时候,已经结束了萌新的状态。

大家想来已经早就听过了关于树和图的传说,但树和图到底是什么呢?又有什么用呢?

大家试想一下,我们现在已知的几种数据结构:栈,队列,链表......这些结构都有一个特点,就是线性的。

这些结构里,从前到后点与点之间的关系是1v1的,而我们不妨思考一下在如下情境中我们该如何存储数据,我们要构造一个这样的情景:

有许多的人,我们知道a比b年龄大,a比c大,d比c大,d比e大......该如何记录这样的信息呢?

如果你能独立想明白的话,我想你已经独立想出了算法中的一大突破,那就是树与图。

我们想一下应该怎么办。是不是本能地想到应该记录一下某个人a和所有与a有关系的人?而这显然一个一维数组我们如果用下标来表示是谁,那么一个值通常是存不下来所有和他有关系的人的。因此我们可以用二维数组来存储,用某一维表示a,然后另一维去存与a有关系的人。

举个例子:

已知有三个人a, b, c, 已知a > b, b > c, a > c

我们可以用一个3 * 3 的数组来记录它,用 1 来表示大于

    a  b  c

a  0  1  1

b  0  0  1

c  0  0  0

这就是一个邻接矩阵, 我们可以从中看出 a 比 b 大, a 比 c大, b 比 c 大

然而邻接矩阵会用节点数目的平方的空间,因此这往往并不适用于节点数目较多而边数较少的情况,所以我们往往会采用另一种方式邻接表,在这种数据结构中,我们记录和每一个顶点有关系的点。

这很方便,以上图为例,如果我们用邻接表的方式,我们所记录的大概是这样:

a : b c

b : c

c :

这同样能够记录图的结构,而消耗的空间很小。

第二种方式又有两种不同的建图方法分别是单链表和动态数组,在讲解建图方式之前,我们不如先来系统地讲述一下图和树的基本概念:

树与图的基本概念

一、图 (Graph)


正如我们前面所讲,图是一种由节点(顶点)和边组成的数据结构,通常用于表示复杂的关系。与树不同,图不要求有层次关系,也不一定是连通的。

1. 图的基本概念


顶点 (Vertex):图中的节点。
边 (Edge):连接两个顶点的线,表示它们之间的关系。
有向图 (Directed Graph):边有方向,即从一个顶点指向另一个顶点。

什么样的关系可以由有向图表示?


无向图 (Undirected Graph):边没有方向,表示两个顶点之间的关系是双向的。

什么样的关系可以由无向图表示?


邻接矩阵 (Adjacency Matrix):使用二维数组表示图的结构,适用于稠密图。
邻接表 (Adjacency List):使用链表数组或动态数组表示图的结构,适用于稀疏图。

二、树(Tree)

树是一种特殊的图!树是无环的连通图。
树是一种分层结构的非线性数据结构,由节点和边组成。每个树由一个根节点和零个或多个子树组成。

1. 树的基本概念
节点(Node):树中的每个元素。
根节点(Root):树的最顶端节点,没有父节点。
父节点(Parent):一个节点的直接前驱节点。
子节点(Child):一个节点的直接后继节点。
叶节点(Leaf):没有子节点的节点。
高度(Height):树中节点的层次,根节点的高度为0。
深度(Depth):节点到根节点的距离。


2. 树的类型
二叉树 (Binary Tree):每个节点最多有两个子节点,通常称为左子节点和右子节点。

完全二叉树:从根结点到倒数第二层满足完美二叉树,最后一层可以不完全填充,其叶子结点都靠左对齐。

建图

建图(树),

我们接下来以这道题为例,从代码的角度来实现一个图的建立,树的建立与图完全一致

一:邻接矩阵建图

节点数量为n

首先创建一个n * n 的二维数组A,初始值默认为0

对每一条由u到v的边,A[u][v] = A[v][u] = 1

二:邻接表建图

动态数组:

创建一个二维动态数组vector<vector<int>> B(n + 1)

对每一条由u到v的边,B[u].push_back(v), B[v].push_back(u)

链表(较难):

这种方法较难,相对来讲比较传统,大家可以自行了解

下面是这道题目的通过代码,希望大家可以先自行尝试解决这道问题

#include <bits/stdc++.h>using namespace std;const int N = 1010, M = 1e5 + 10;// 邻接矩阵
int A[N][N];// 邻接表
vector<vector<int>> B(N);int main()
{int n, m;cin >> n >> m;for (int i = 1; i <= m; i ++ ){int a, b;cin >> a >> b;// 邻接矩阵存储边A[a][b] = A[b][a] = 1;// 邻接表存储边B[a].push_back(b);B[b].push_back(a);}for (int i = 1; i <= n; i ++ ){for (int j = 1; j <= n; j ++ ){cout << A[i][j] << " ";}cout << endl;}for (int i = 1; i <= n; i ++ ){// 一个点相关的边的数量等于这个点的度数cout << B[i].size() << " ";// 题目中要求从小到大输出sort(B[i].begin(), B[i].end());for (auto b : B[i]){cout << b << " ";}cout << endl;}return 0;
}

图(树)的深度优先搜索

大家已经学习过在网格图中如何进行搜索,那么在图中该怎么进行搜索呢?我们这里仅讲述dfs,bfs与其类似,大家可以课后自行尝试

在网格图中,我们通常使用上下左右四个方向来进行移动,但是在图和树中,一个点能移动到的位置是所有与其相连的点

我们用邻接表来讲的话,其dfs大概是这样的

// 邻接表
vector<vector<int>> B(N);// u是当前访问的节点,fa是上一个节点
void dfs(int u, int fa)
{// b 是相连的点for (auto b : B[u]){// 如果不是父节点,就移动过去,这避免了在两个点之间反复横跳if (b != fa){dfs(b, u);}}
}

二叉树的前中后遍历

在前文中,我们如果要去遍历图,遍历的顺序取决于给出边的顺序

举个例子,如果给出12 13 14, 我们会先访问2, 再访问3,再访问4

如果给出的是 13 12 14, 这个时候,顺序就变为了3 2 4

但是在二叉树中,我们知道一个点可以有左子节点和右子节点,如果我们按照某种顺序去访问其左子节点右子节点和其本身,那么就会得到相对来讲比较特殊的遍历顺序

前序遍历:根结点 ---> 左子树 ---> 右子树

中序遍历:左子树---> 根结点 ---> 右子树

后序遍历:左子树 ---> 右子树 ---> 根结点

如果课堂时间有剩余或者大家学有余力的话,我们不如一起来思考一下这些问题:

如何记录二叉树的左子节点和右子节点?

如果用链表去做的话怎么做邻接表?

在博客开头的情境里,能否根据已有信息排列出一个明确的年龄顺序,什么情况下可以?什么情况下不行?

结语

关于树与图的知识还有很多,欢迎大家有不懂的知识来问学长学姐,希望大家能够通过思考提高自己的思维能力,算法能力猛猛进步!

感谢阅读!

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

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

相关文章

HTML 日常开发常用标签

文章目录 HTML 日常开发常用标签1、基本结构标签2、内容标签3、多媒体标签4、表单标签5、列表和定义标签6、表格标签7、链接和图像8、元数据9、语义化标签&#xff08;HTML5新增&#xff09;10、框架和内联11、交互12、过时或不推荐使用的标签 HTML 日常开发常用标签 1、基本结…

7.1.1 计算机网络的组成

文章目录 物理组成功能组成工作方式完整导图 物理组成 计算机网络是将分布在不同地域的计算机组织成系统&#xff0c;便于相互之间资源共享、传递信息。 计算机网络的物理组成包括硬件和软件。硬件中包含主机、前端处理器、连接设备、通信线路。软件中包含协议和应用软件。 功…

【AI论文】MedVLM-R1:通过强化学习激励视觉语言模型(VLMs)的医疗推理能力

摘要&#xff1a;推理是推进医学影像分析的关键前沿领域&#xff0c;其中透明度和可信度对于赢得临床医生信任和获得监管批准起着核心作用。尽管医学视觉语言模型&#xff08;VLMs&#xff09;在放射学任务中展现出巨大潜力&#xff0c;但大多数现有VLM仅给出最终答案&#xff…

国产RISCV64 也能跑AI

Banana Pi BPI-F3 进控时空 K1开发板 AI人工智能AI 部署工具使用手册_bianbu software-CSDN博客 文章置顶了 有兴趣的可以一起留言探索&#xff0c;非常有意思&#xff1a; 我最近接触到了进迭时空研发的 Spacengine™&#xff0c;这是一套能在进迭时空 RISC-V 系列芯片上部署…

APISIX Dashboard上的配置操作

文章目录 登录配置路由配置消费者创建后端服务项目配置上游再创建一个路由测试 登录 http://192.168.10.101:9000/user/login?redirect%2Fdashboard 根据docker 容器里的指定端口&#xff1a; 配置路由 通过apisix 的API管理接口来创建&#xff08;此路由&#xff0c;直接…

【WPF】绑定报错:双向绑定需要 Path 或 XPath

背景 最开始使用的是 TextBlock: <ItemsControl ItemsSource"{Binding CameraList}"><ItemsControl.ItemsPanel><ItemsPanelTemplate><StackPanel Orientation"Horizontal"/></ItemsPanelTemplate></ItemsControl.Item…

Kotlin协变与逆变区别

在Kotlin中&#xff0c;协变和逆变是泛型编程中的两个重要概念&#xff0c;它们允许我们在类型系统中更加灵活地处理类型关系。 1.协变&#xff1a;协变允许我们使用比原始类型更具体的类型。在kotlin中&#xff0c;通过在类型参数上加out关键字来表示协变,生产者&#xff0c;例…

如何调试Linux内核?

通过创建一个最小的根文件系统&#xff0c;并使用QEMU和GDB进行调试。 1.准备工作环境 确保系统上安装了所有必要的工具和依赖项。 sudo apt-get update //更新一下软件包 sudo apt-get install build-essential git libncurses-dev bison flex libssl-dev qemu-system-x…

Java 调试模式下 Redisson 看门狗失效

一、场景分析 前几天在做分布式锁测试&#xff1a; 在调试模式下&#xff0c;lock.lock() 之后打上断点&#xff0c;想测试一下在当前线程放弃锁之前&#xff0c;别的线程能否获取得到锁。 发现调试模式下&#xff0c;看门狗机制失效了&#xff0c;Redis 上 30 秒后&#xff0…

GPT-4.5震撼登场,AI世界再掀波澜!(3)

GPT-4.5震撼登场&#xff0c;AI世界再掀波澜! GPT-4.5震撼登场&#xff0c;AI世界再掀波澜!(2) &#xff08;一&#xff09;伦理困境&#xff1a;如何抉择 GPT-4.5 的强大功能在为我们带来诸多便利的同时&#xff0c;也引发了一系列深刻的伦理问题&#xff0c;这些问题犹如高…

【数据挖掘】Pandas

Pandas 是 Python 进行 数据挖掘 和 数据分析 的核心库之一&#xff0c;提供了强大的 数据清洗、预处理、转换、分析 和 可视化 功能。它通常与 NumPy、Matplotlib、Seaborn、Scikit-Learn 等库结合使用&#xff0c;帮助构建高效的数据挖掘流程。 &#x1f4cc; 1. 读取数据 P…

七、JOIN 语法详解与实战示例

一、JOIN 的作用与分类 JOIN 操作用于合并两个或多个表的行&#xff0c;基于表之间的关联字段。以下是常见的 JOIN 类型&#xff1a; JOIN 类型描述INNER JOIN返回两个表匹配的记录LEFT JOIN返回左表所有记录 右表匹配记录&#xff08;右表无匹配则为NULL&#xff09;RIGHT …

2019年01月全国POI数据分享(同源历史POI分享系列)

2019年01月全国范围POI数据 2019年01月份全国范围历史POI数据&#xff0c;全国范围所有类别共59336781个POI 2019年01月全国范围POI数据按大类统计 大类代码大类名称2019年01月该类POI数量010000汽车服务1151164020000汽车销售213647030000汽车维修517367040000摩托车服务1800…

Spring Boot + MyBatis 实现 RESTful API 的完整流程

后端开发&#xff1a;Spring Boot 快速开发实战 引言 在现代后端开发中&#xff0c;Spring Boot 因其轻量级、快速开发的特性而备受开发者青睐。本文将带你从零开始&#xff0c;使用 Spring Boot MyBatis 实现一个完整的 RESTful API&#xff0c;并深入探讨如何优雅地处理异…

使用Python开发以太坊智能合约:轻松入门与深度探索

使用Python开发以太坊智能合约&#xff1a;轻松入门与深度探索 随着区块链技术的快速发展&#xff0c;以太坊作为最为成熟和广泛使用的智能合约平台&#xff0c;成为了开发去中心化应用&#xff08;DApp&#xff09;的核心工具。智能合约不仅是区块链技术的基础&#xff0c;更…

ES scroll=1m:表示快照的有效时间为1分钟。怎么理解

在Elasticsearch中&#xff0c;scroll1m 表示你创建的 scroll 上下文 的有效时间为 1分钟。这个参数控制了你可以在多长时间内继续使用这个 scroll_id 来获取更多的数据。 什么是 Scroll 上下文&#xff1f; 当你使用 scroll API 时&#xff0c;Elasticsearch 会为你的查询创…

Linux与UDP应用1:翻译软件

UDP应用1&#xff1a;翻译软件 本篇介绍 本篇基于UDP编程接口基本使用中封装的服务器和客户端进行改写&#xff0c;基本功能如下&#xff1a; 从配置文件dict.txt读取到所有的单词和意思客户端向服务端发送英文服务端向客户端发送英文对应的中文意思 配置文件内容 下面的内…

Jeecg-Boot 开放接口开发实战:在 Jeecg-Boot 的jeecg-system-biz中添加一个controller 实现免鉴权数据接口

Jeecg-Boot 开放接口开发实战&#xff1a;在 Jeecg-Boot 的jeecg-system-biz中添加一个controller 实现免鉴权数据接口 一、场景需求分析 在微服务架构中&#xff0c;常需要快速实现以下两类接口&#xff1a; 开放接口&#xff1a;无需登录即可访问&#xff08;如数据查询、…

C++ ++++++++++

初始C 注释 变量 常量 关键字 标识符命名规则 数据类型 C规定在创建一个变量或者常量时&#xff0c;必须要指定出相应的数据类型&#xff0c;否则无法给变量分配内存 整型 sizeof关键字 浮点型&#xff08;实型&#xff09; 有效位数保留七位&#xff0c;带小数点。 这个是保…

构建安全的Docker基础镜像:从最佳实践到自动化加固

引言 容器化技术的普及使得Docker镜像成为软件交付的核心载体,但镜像中的安全漏洞、敏感信息泄露和权限配置不当等问题可能引发严重风险。本文结合OWASP容器安全指南与一线运维经验,系统化讲解如何构建安全的Docker基础镜像,覆盖镜像构建、依赖管理、运行时防护全链路,并提…