数据结构--》连接世界的无限可能—— 图

        图作为数据结构中的一种重要概念,扮演着连接世界的纽带。与树和二叉树相比,图更加灵活和多样化,它能够描述各种实际问题中的复杂关系,如社交网络中的人际联系、城市交通中的路线规划以及电子网络中的通信路径等。

        无论你是初学者还是进阶者,本文将为你提供简单易懂、实用可行的知识点,帮助你更好地掌握图在数据结构和算法中的重要性,进而提升算法解题的能力。接下来让我们开启数据结构与算法的奇妙之旅吧。

目录

图的基本概念

图的存储表示

图的基本操作

图的遍历与连通性

最小生成树 

最短路径问题

关键路径问题


图的基本概念

图是由一组顶点(节点)和连接这些顶点的边(关系)组成的非线性数据结构。图用于表示元素之间的关系,通过节点和边来描述图中元素之间的连接情况。

图的定义包括以下几个要素

顶点:图中的节点表示实体或对象,通常用圆圈或方框来表示。每个节点可以包含一些相关信息,如名称、属性等。

:图中的边表示顶点之间的关系,用于连接不同的顶点。边可以是有向的(箭头表示方向)或无向的(不带箭头表示),也可以带有权重(表示边的权值)。

邻接点:对于一个顶点,与它直接相连的顶点称为邻接点。邻接点之间通过边相连。

路径:路径是指顶点之间经过的一系列边的序列。路径的长度可以通过经过的边的数量来计算。

:如果路径的起点和终点是同一个顶点,并且至少经过了一条边,就形成了一个圈。圈也被称为循环。

有向图和无向图

顶点的度

对于无向图而言,顶点v的度是指依附于该顶点的边的条数,记为TD(v)。

对于有向图而言,我们要探讨的是顶点的入度和出度:

顶点v的度等于入度和出度之和,即 TD(v) = ID(v) + OD(v)。

入读是以顶点v为终点的有向边的数目,记为ID(V);出度是以顶点v为起点的有向边的数目,记为OD(v)。

顶点与顶点之间的关系描述

连通图和强连通图

子图:(研究图的局部)

对于有向图来说子图和生成子图的概念也是一样的:

连通分量

无向图中的极大连通子图称为连通分量:

有向图中的极大强连通子图称为有向图的强连通分量:

生成树

连通图的生成树是包含图中全部顶点的一个极小连通子图。

生成森林

在非连通图中,连通分量的生成树构成了非连通图的生成森林。

几种特殊形态的图

回顾重点,其主要内容整理成如下内容:

图的存储表示

图可以用多种方式进行存储表示,常见的有两种主要方法:邻接矩阵和邻接表。

邻接矩阵法

邻接矩阵是一个二维数组,用于表示图中的节点之间的连接关系。对于一个有n个节点的图,邻接矩阵是一个大小为n×n的方阵。如果节点i和节点j之间存在一条边,则邻接矩阵中第i行第j列的元素为1;否则为0。邻接矩阵的优点是可以快速判断任意两个节点之间是否有边,但缺点是当图比较稀疏时会占用大量的空间。

如果我们采用邻接矩阵法存储带权图(网):

邻接表法

根据有向无向连判断当前结点所连接的下一个结点的索引:

回顾重点,其主要内容整理成如下内容: 

十字链表法存储有向图

邻接多重表存储无向图

如果删除结点和边的话得到的相应结果如下:

回顾重点,其主要内容整理成如下内容:

图的基本操作

如果我们想知道两个结点之间是否存在边可以通过邻接矩阵或者邻接表的方式:

如果我们想在图中插入顶点x,可以采用如下的方式进行:

如果想在图中删除某个顶点x,可以采用如下的方式进行:

如果想知道图中顶点x的第一个邻接点,若有则返回顶点号,若x没有邻接点或图中不存在x,则返回-1:

图的遍历与连通性

图的遍历是指访问图中所有节点的过程。通过遍历,我们可以对图的结构和节点之间的关系进行全面的了解。常用的图遍历算法包括广度优先搜索(BFS)和 深度优先搜索(DFS)。

广度优先遍历:图的广度优先遍历(Breadth-First Search,BFS)是一种从起始节点开始,先访问离起点最近的节点,然后逐层向外扩展访问的策略。它保证了先访问距离起始节点相近的节点,然后再访问距离稍远的节点。

广度优先遍历序列的案例如下:

下面是用 C 语言实现图的广度优先遍历的基本代码示例:

#include <stdio.h>#define MAX_NODES 100typedef struct {int neighbor[MAX_NODES];int numNeighbors;int visited;
} Node;void bfs(Node graph[], int start, int numNodes) {int queue[MAX_NODES];int front = 0, rear = 0;// 将起始节点加入队列并标记为已访问queue[rear++] = start;graph[start].visited = 1;while (front != rear) {int current_node = queue[front++];  // 队首节点出队printf("%d ", current_node);  // 访问当前节点// 遍历当前节点的邻居节点for (int i = 0; i < graph[current_node].numNeighbors; i++) {int neighbor = graph[current_node].neighbor[i];if (!graph[neighbor].visited) {  // 如果邻居节点未被访问过queue[rear++] = neighbor;  // 将邻居节点入队graph[neighbor].visited = 1;  // 标记邻居节点为已访问}}}
}int main() {// 创建一个示例图Node graph[MAX_NODES];// 初始化图中的节点和边for (int i = 0; i < MAX_NODES; i++) {graph[i].numNeighbors = 0;graph[i].visited = 0;}// 添加边关系graph[0].neighbor[graph[0].numNeighbors++] = 1;graph[0].neighbor[graph[0].numNeighbors++] = 2;graph[1].neighbor[graph[1].numNeighbors++] = 3;graph[2].neighbor[graph[2].numNeighbors++] = 4;graph[2].neighbor[graph[2].numNeighbors++] = 5;graph[3].neighbor[graph[3].numNeighbors++] = 6;graph[4].neighbor[graph[4].numNeighbors++] = 7;// 进行广度优先遍历bfs(graph, 0, 8);  // 假设图中有 8 个节点return 0;
}

广度优先生成树用于在一个无向图或有向图中从给定的起始节点开始,以广度优先的方式生成一个树状结构,该树包含了从起始节点出发到达所有可达节点的最短路径。 

回顾重点,其主要内容整理成如下内容:

深度优先遍历:深度优先搜索(Depth-First Search,DFS)是一种先走尽可能远的策略,即沿着当前路径走到底,直到不能再走下去为止,然后回溯到前一个节点,继续探测其他路径,直到所有节点都被访问过。

深度优先生成树是指通过深度优先搜索算法生成的一棵树状结构,该树包含了从给定起始节点出发到达所有可达节点的最短路径。

下面是用 C 语言实现深度优先遍历的基本代码示例:

#include <stdio.h>#define MAX_NODES 100typedef struct {int neighbor[MAX_NODES];int numNeighbors;int visited;
} Node;void dfs(Node graph[], int current_node) {printf("%d ", current_node);  // 先访问当前节点graph[current_node].visited = 1;  // 标记当前节点为已访问// 遍历当前节点的邻居节点,递归调用 dfs 函数for (int i = 0; i < graph[current_node].numNeighbors; i++) {int neighbor = graph[current_node].neighbor[i];if (!graph[neighbor].visited) {  // 如果邻居节点未被访问过dfs(graph, neighbor);  // 递归访问邻居节点}}
}int main() {// 创建一个示例图Node graph[MAX_NODES];// 初始化图中的节点和边for (int i = 0; i < MAX_NODES; i++) {graph[i].numNeighbors = 0;graph[i].visited = 0;}// 添加边关系graph[0].neighbor[graph[0].numNeighbors++] = 1;graph[0].neighbor[graph[0].numNeighbors++] = 2;graph[1].neighbor[graph[1].numNeighbors++] = 3;graph[2].neighbor[graph[2].numNeighbors++] = 4;graph[2].neighbor[graph[2].numNeighbors++] = 5;graph[3].neighbor[graph[3].numNeighbors++] = 6;graph[4].neighbor[graph[4].numNeighbors++] = 7;// 进行深度优先遍历dfs(graph, 0);  // 假设从节点 0 开始遍历return 0;
}

连通分量

连通分量是指一个无向图中的最大连通子图。连通分量由若干个顶点及它们之间的边组成,其中每个顶点都可以通过路径与其他顶点相互到达。

在无向图中,连通分量可以非常直观地理解为图中的一片区域,该区域中的所有顶点都可以彼此到达。每个连通分量都是图的一部分,并且一个图可以有多个连通分量。

在有向图中,连通分量的定义相对复杂一些。有向图的连通性需要考虑顶点之间的有向路径。有向图中的连通分量是指在该图中,每个顶点都存在至少一条有向路径可以到达其他所有顶点。

回顾重点,其主要内容整理成如下内容: 

最小生成树 

最小生成树是指在无向带权连通图中,寻找一棵包含所有顶点的生成树,并且该树的所有边的权值之和最小。最小生成树有以下特点:

最小生成树可能是多个;最小生成树中的边数等于顶点数减1;最小生成树中不会有回路。

常见的解决最小生成树问题的算法包括 Prim算法Kruskal算法

Prim算法(普里姆):从某一个顶点开始构建生成树;每次将代价最小的新顶点纳入生成树,直到所有的顶点都纳入为止。

这里我们选择p城为根结点,然后依次向外扩张找连线之间代价最小的结点,最终得到最小代价:

Kruskal算法(克鲁斯卡尔):每次选择一条权值最小的边,使这条边的两头连通(原本已经连通的就不选)直到所有的结点都连通。

两种算法的比较:

最短路径问题

图的最短路径问题是指在一个加权有向图或无向图中,寻找两个顶点之间最短路径的问题。最短路径可以通过边的权值和来衡量。最短路径问题主要分为以下两种情况:

单源最短路径:从给定的一个起始节点到图中其他所有节点之间的最短路径。它可以用于解决从一个固定起点到其他节点的最短路径问题。

BFS算法(无权图):

Dijkstra算法(带权图、无权图):

各顶点间的最短路径:计算图中任意两个节点之间的最短路径。它可以用于解决任意节点对之间的最短路径问题。

Floyd算法(带权图、无权图):

回顾重点,其主要内容整理成如下内容:  

关键路径问题

关键路径是指项目计划中不能延误的最长路径,它决定了整个项目的最短完成时间。关键路径问题常用于项目管理和工程规划中。

在AOE网中我们要了解以下概念:

根据上文相关例子的举出之后,接下来我们开始计算相应的数值:

求所有事件的最早发生时间:(等最慢的完成才可以)

求所有事件的最迟发生事件:(汇点的最迟发生时间与最早发生时间一致,我们以汇点为触发点你拓扑排序,即减去相应路径上发生的事件从而得到该点的最迟发生时间):

求所有活动的最早发生时间:(通过前面计算处的事件最早发生时间推算出活动最早发生时间):

求所有活动的最晚发生时间:(通过前面计算处的事件最迟发生时间减去相应活动需要的时间得出)

求所有活动的时间余量:(活动最晚发生时间减去活动最早发生时间)

注意:以下是相应的关键活动和关键路径的特性:

回顾重点,其主要内容整理成如下内容: 

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

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

相关文章

python:从Excel或者CSV中读取因变量与多个自变量,用于训练机器学习回归模型,并输出预测结果

作者:CSDN @ _养乐多_ 本文详细记录了从Excel读取用于训练机器学习模型的数据,包括独立变量和因变量数据,以供用于机器学习模型的训练。这些机器学习模型包括但不限于随机森林回归模型(RF)和支持向量机回归模型(SVM)。随后,我们将测试数据集应用于这些模型,进行预测和…

[开源]基于流程编排的自动化测试工具,插件驱动,测试无限可能

一、开源项目简介 流程编排&#xff0c;插件驱动&#xff0c;测试无限可能 一款基于流程编排的自动化测试工具 二、开源协议 使用Apache-2.0开源协议 三、界面展示 四、功能概述 在软件开发旅程中&#xff0c;测试流程的管理和执行常常是复杂且耗时的挑战。传统测试工具主…

spring6项目搭建(入门)

文章目录 环境要求构建模块引入依赖初试Bean创建测试类测试对象实现的原理 环境要求 JDK&#xff1a;Java17&#xff08;Spring6要求JDK最低版本是Java17&#xff09; Maven&#xff1a;3.6 Spring&#xff1a;6.0.2 构建模块 首先建立的spring的项目&#xff08;project&…

如何使用Jmeter进行http接口测试?

前言&#xff1a; 本文主要针对http接口进行测试&#xff0c;使用Jmeter工具实现。 Jmter工具设计之初是用于做性能测试的&#xff0c;它在实现对各种接口的调用方面已经做的比较成熟&#xff0c;因此&#xff0c;本次直接使用Jmeter工具来完成对Http接口的测试。 一、开发接…

STM32使用HAL库驱动TA6932数码管驱动芯片

TA6932介绍 8段16位&#xff0c;支持共阴共阳LED数码管。 2、STM32CUBEMX配置引脚 推挽配置即可。 3、头文件 /******************************************************************************************** * TA6932&#xff1a;8段16位数码管驱动 *******************…

vue3封装分页组件

1.新建Pagination文件以及该文件夹下新建index.vue 2.在index.vue文件中编写一下代码 <template><div :class"{ hidden: hidden }" class"pagination-container"><el-pagination:background"background"v-model:current-page&qu…

GPU 基础知识整理

萌新&#xff1a; 在接触一款硬件时我会&#xff1a;基础硬件结构&#xff0c;线程结构&#xff0c;内存布局&#xff0c;数据吞吐量&#xff0c;等方面进行学习 首先GPU的特点: 并行性能&#xff1a;GPU 是专门设计用于并行计算的硬件&#xff0c;通常具有大量的处理单元&am…

文字与视频结合效果

效果展示 CSS 知识点 mix-blend-mode 属性的运用 实现整体页面布局 <section class"sec"><video autoplay muted loop><source src"./video.mp4" type"video/mp4" /></video><h2>Run</h2><!-- 用于切…

免费在线真好用的思维脑图

大家好这里是tony4geek 。 今天给大家介绍一个工具。思维脑图生成器。最近写文章需要用到思维脑图&#xff0c;如果手上没有xmind 这种类工具是挺麻烦的。下载xmind 还得破解注册很费时间。 看看有没有在线生成的&#xff0c;找了好久没有找到合适的&#xff0c;最后在国外一…

Python接口自动化测试之【测试函数、测试类/测试方法的封装】

前言 在pythonpytest 接口自动化系列中&#xff0c;我之前的文章基本都没有将代码进行封装&#xff0c;但实际编写自动化测试脚本中&#xff0c;我们都需要将测试代码进行封装&#xff0c;才能被测试框架识别执行。 例如单个接口的请求代码如下&#xff1a; import requests…

Vue—大文件分片上传

背景 如题&#xff0c;最近遇到大文件上传慢的问题&#xff0c;用户需要经常上传一些超过一百多M的文件&#xff0c;系统由于历史原因上传功能并没有做分片上传的功能&#xff0c;是整个文件上传&#xff0c;并且服务器带宽限制和NGINX对文件大小的限制等问题&#xff0c;所以…

【excel技巧】如何在Excel表格中添加选项按钮?

不知道大家是否会9遇到需要勾中选项的情况&#xff0c;我们可以在电子表格中制作出可以勾选、选中的选项按钮&#xff0c;今天我们一起学习一下设置方法。 首先&#xff0c;我们需要先在excel工具栏中添加一个功能模块&#xff1a;开发工具 依次点击excel中的文件 – 选项 –…

炒现货白银的最佳时间

天时地利人和是我们进行现货白银投资最关键的因素。天时是指我们因时而动&#xff0c;在适合的时机出击。地利&#xff0c;就是我们对市场的定位&#xff0c;对自己入场的定位有清晰的了解&#xff0c;并且这些位置对我们有利。人和就是指投资者的状态很好&#xff0c;对如何进…

数学建模——确定性时间序列分析方法

目录 介绍 确定性时间序列分析方法 1、时间序列的常见趋势 &#xff08;1&#xff09;长期趋势 &#xff08;2&#xff09;季节变动 &#xff08;3&#xff09;循环变动 &#xff08;4&#xff09;不规则变动 常见的时间序列模型有以下几类 2、时间序列预测的具体方法 …

1000个已成功入职的软件测试工程师简历范文模板(含真实简历)

如果你想学习自动化测试&#xff0c;那么下面这套视频应该会帮到你很多 如何逼自己1个月学完自动化测试&#xff0c;学完即就业&#xff0c;小白也能信手拈来&#xff0c;拿走不谢&#xff0c;允许白嫖.... 最后我这里给你们分享一下我所积累和整理的一些文档和学习资料&#…

EDUSRC-记一个SHELL捡漏

目录 ​编辑 Jenkins - println绕过到shell命令执行 语法 Jenkins未授权访问(捡漏失败) Jenkins捡漏 弱口令 脚本执行(println失败) CHATGPT调教绕过 hack渗透视频教程&#xff0c;扫码免费领 Jenkins - println绕过到shell命令执行 语法 org"China Education and…

IDEA插件版本升级和兼容新版本idea

1.关于IDEA插件的版本设置问题 打开jetbrains插件市场&#xff0c;随意打开一个插件详情页面的Versions菜单&#xff0c;我们可以看见一个插件包不同时期发布的不同版本&#xff08;Versions&#xff09;&#xff0c;并且每个版本包含了可兼容IDEA或PyCharm的版本范围&#xf…

Avalonia常用小控件Menu

1.项目下载地址&#xff1a;https://gitee.com/confusedkitten/avalonia-demo 2.UI库Semi.Avalonia&#xff0c;项目地址 https://github.com/irihitech/Semi.Avalonia 样式预览&#xff1a; axaml代码 &#xff1a; <UserControl xmlns"https://github.com/avalo…

【个人博客公网访问】使用Cpolar+Emlog在Ubuntu上轻松搭建个人博客公网访问

文章目录 前言1. 网站搭建1.1 Emolog网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总结 前言 博客作为使…

性能测试 —— 生成html测试报告、参数化、jvm监控

1.生成HTML的测试报告 1.1配置 (1)找到jmeter 的安装目录&#xff0c;下的bin中的jmeter.properties&#xff08;jmeter配置文件&#xff09; (2) ctrl f &#xff0c;搜索jmeter.save.saveservice.output_format&#xff0c;取消井号 并且 把等号后的xml改为csv&#xff0c;…