数据结构不再难懂:带你轻松搞定图

数据结构入门学习(全是干货)——图

1 图

1.1 什么是图

图是一种用于表示多对多关系的数学模型。它由一组顶点和一组边构成,用于描述事物之间的复杂关联。

  • 顶点:通常用 V (Vertex) 表示,代表事物或对象。
  • :通常用 E (Edge) 表示,代表顶点之间的连接。边可以是无向的(双向)或有向的(单向)。
    • 无向边(v, w),表示顶点 vw 之间相互连接,没有方向性。
    • 有向边<v, w>,表示从 vw 有方向的连接。
图的抽象数据类型 (ADT)
  • 类型名称:图 (Graph)

  • 数据对象G(V, E) 表示图由顶点集合 V 和边集合 E 构成。顶点集合不能为空,但边可以为空。

  • 操作

    • 添加顶点和边。
    • 遍历图的所有顶点和边。
    • 查询图的属性,如顶点的度数、两顶点之间是否存在边等。
    
    1. Graph Create():建立并返回空图
    2. Graph InsertVertex(Graph G, Vertex v):将v插入G
    3. Graph InsertEdge(Graph G, Edge e):将e插入G;
    4. void DFS(Graph G,Vertex v):从顶点v出发深度优先遍历图G;
    5. void BFS(Graph G,Vertex v):从顶点v出发宽度优先遍历图G;
    6. void ShortestPath(Graph G,Vertex v,int Dist[]):计算图G中顶点v到任意其他顶点的最短距离
    7. void MST(Graph G):计算图G的最小生成树
    
常见术语
  1. 无向图:没有方向的边连接顶点。
  2. 有向图:每条边都有方向,如箭头从一个顶点指向另一个顶点。
  3. 权重:边上标记的数字,通常表示该连接的成本、距离或权值。
  4. 网络:带权重的图称为网络。

1.2 图的表示法——邻接矩阵

邻接矩阵是一种常用的表示图的方法,使用二维数组表示顶点之间的连接关系。

  • 无向图:邻接矩阵是对称的。matrix[i][j] 表示顶点 i 和顶点 j 之间是否有边。
  • 有向图:矩阵的行和列代表了方向关系,matrix[i][j] 表示从顶点 i 到顶点 j 是否有边。

怎么在程序中表示一个图

邻接矩阵的优缺点
  • 优点

    • 直观、简单,易于理解和实现。
    • 检查任意两个顶点间是否有边十分方便。
    • 快速找到某一顶点的邻接点和计算顶点的度(有向图中分为出度和入度)。
  • 缺点

    • 对于稀疏图(顶点多而边少),邻接矩阵会浪费大量存储空间。
    • 对稀疏图,统计边的数量会比较耗时。

1.3 图的表示法——邻接表

邻接表是另一种表示图的方法,适用于稀疏图

  • 每个顶点对应一个链表,链表中的节点存储的是该顶点的所有邻接点。
  • 无向图:每条边 (v, w) 会在 vw 的链表中各自存储一次。
  • 有向图:每条有向边 <v, w> 只会在 v 的链表中存储。

邻接表的优缺点
  • 优点

    • 更适合存储稀疏图,节省空间。
    • 找出一个顶点的所有邻接点非常高效。
    • 适合计算顶点的度。
  • 缺点

    • 检查任意两个顶点是否相邻需要遍历链表,效率不如邻接矩阵。
    • 不能快速统计边的数量。

2 图的遍历

图的遍历就是访问图中每个顶点一次,遍历过程中要确保每个顶点只访问一次。图的遍历通常有两种主要方法:深度优先搜索 (DFS) 和广度优先搜索 (BFS)。

2.1 图的遍历——深度优先搜索 (DFS)

深度优先搜索是一种递归的遍历方法,沿着图中的一条路径一直走到底,再回溯到上一层节点,继续沿另一条路径遍历,直至遍历所有顶点。

DFS 算法步骤:
  1. 从某个顶点开始,标记为已访问。
  2. 递归访问该顶点的未访问邻接点,直到所有邻接点都被访问。
  3. 回溯到上一个顶点,重复上述过程,直到遍历完所有顶点。

DFS 的实现可以用递归或显示栈来管理回溯过程。

void DFS(Vertex V)//从迷宫的节点出来
{visited[V] = true;//给每个节点一个变量,true相当于灯亮了,false则是熄灭状态for(V的每个邻接点W)//视野看得到的灯if(!visited[W])//检测是否还有没点亮的DFS(W);//递归调用
}//类似树的先序遍历
若有N个顶点、E条边,时间复杂度是用邻接表存储图,有O(N+E)//对每个点访问了一次,每条边也访问了一次用邻接矩阵存储图,有O()//V对应的每个邻接点W都要访问一遍
DFS 的时间复杂度:
  • 对于使用邻接表存储的图,时间复杂度为 O(V + E),其中 V 是顶点数,E 是边数。
  • 对于使用邻接矩阵存储的图,时间复杂度为 O(V^2)

2.2 图的遍历——广度优先搜索 (BFS)

广度优先搜索是一种层次遍历方法,从某个顶点出发,依次访问所有距离该顶点为一层的节点,然后再访问下一层节点,直到所有节点都被访问。

BFS 算法步骤:

void BFS(Vertex V)
{visited[V] = true;Enqueue(V,Q);//压到队列里while(!IsEmpty(Q)){V = Dequeue(Q);//每次循环弹出一个节点for(V的每个邻接点W)if(!visited[W]){//没有访问过的去访问将其压入队列中visited[W] = true;Enqueue(W,Q);}}
}
  1. 从某个顶点开始,标记为已访问并将其加入队列。
  2. 从队列中取出顶点,访问它的所有未访问的邻接点,并将这些邻接点加入队列。
  3. 重复上述过程,直到队列为空,表示所有顶点都已访问。
BFS 的时间复杂度:
  • 对于使用邻接表存储的图,时间复杂度为 O(V + E)
  • 对于使用邻接矩阵存储的图,时间复杂度为 O(V^2)

2.3 为什么需要两种遍历方法?

  • DFS:适用于需要尽可能深入遍历的情况,特别是当需要探索路径时,比如解决迷宫问题。
  • BFS:适用于需要层次遍历的情况,如寻找最短路径等。

2.4 图不连通怎么办?

在遍历图时,如果图不连通,意味着某些顶点无法通过一条路径到达其他顶点。此时,需要对每个连通分量分别进行遍历。

连通的相关概念:
  • 连通图:在无向图中,任意两个顶点之间都有路径。
  • 连通分量:无向图中的极大连通子图。
  • 回路:从一个顶点出发,经过若干条边回到起始顶点的路径。

在遍历非连通图时,可以使用 DFS 或 BFS 多次遍历,每次从未访问的顶点开始,直到遍历完所有连通分量。


3 应用实例:拯救 007

在这个应用实例中,可以通过图的遍历(DFS 或 BFS)来模拟 007 从一个顶点逃脱到另一个顶点的场景。目标是从起始顶点开始,找到一条通往安全点的路径。


void Save007(Graph G)
{for(each V in G){if(!visited[V] && FirstJump(V)){//这个FirstJump(V)是007第一跳有没有可能从孤岛跳到V上有没有可能,有且没踩过就跳上去answer = DFS(V);//or BFS(V)if(answer == YES) break;0}}if(answer == YES) output("Yes");else output("No");
}
DFS 解决方案:
  1. 以起点作为图中的一个顶点。
  2. 使用 DFS 递归地查找逃脱路径。
  3. 如果找到了逃脱路径,输出路径;如果没有找到,则输出“没有路径”。

void DFS(Vertex V)
{visited[V] = true;//表示鳄鱼头踩过了if(IOsSafe(V)) answer = YES;else{for(each W in G )if(!visited[W] && Jump(V,W)){//可以从V jump跳到这个w上面,作用是算V到W之间的距离是不是小于007可以跳跃最大距离answer = DFS(W);//递归 if(answer == YES) break;}}return answer;
}
BFS 解决方案:
  1. 从起点开始,使用队列存储每个可能的逃脱路径。
  2. 广度优先地寻找最短逃脱路径。
  3. 输出找到的路径,如果没有找到,输出“没有路径”。

4 应用实例:六度空间理论

六度空间理论 (Six Degrees of Separation) 表示在一个社交网络中,任意两个人之间通过不超过六个人的中间连接,就可以建立联系。

社交网络图:
  1. 将社交网络建模为一个无向图,顶点表示人,边表示两个人之间的社交联系。
  2. 通过图的遍历(如 BFS)计算每个人到其他人的最短路径,验证六度空间理论的正确性。
  3. 计算符合六度空间理论的顶点数量占总顶点数量的百分比。
算法思路
1.对每个节点进行广度优先搜索
2.搜索过程中累计访问的节点数
3.需要记录"层",仅计算6层以内的节点数void SDS()
{for(each V in G){count += BFS(V);Output = (count/N);}
}//结合最初的BFSvoid BFS(Vertex V)
{visited[V] = true;count = 1;Enqueue(V,Q);//压到队列里while(!IsEmpty(Q)){V = Dequeue(Q);//每次循环弹出一个节点for(V的每个邻接点W)if(!visited[W]){//没有访问过的去访问将其压入队列中visited[W] = true;Enqueue(W,Q);count++;}}return count;
}


5 小白专场:如何用 C 语言建立图

在 C 语言中,图的实现通常使用邻接矩阵或邻接表来存储顶点和边的关系。

5.1 邻接矩阵实现

邻接矩阵的结构:
typedef struct {int VertexNum;int EdgeNum;int Matrix[MAXV][MAXV]; // 邻接矩阵
} MGraph;
初始化图:
MGraph* CreateGraph(int VertexNum) {MGraph *Graph = (MGraph *)malloc(sizeof(MGraph));Graph->VertexNum = VertexNum;Graph->EdgeNum = 0;for (int i = 0; i < VertexNum; i++) {for (int j = 0; j < VertexNum; j++) {Graph->Matrix[i][j] = 0; // 初始化无边的图}}return Graph;
}
插入边:
void InsertEdge(MGraph *Graph, int v1, int v2, int weight) {Graph->Matrix[v1][v2] = weight; // 插入边 v1 -> v2Graph->EdgeNum++;
}

5.2 邻接表实现

邻接表的结构:
typedef struct AdjVNode {int AdjV;struct AdjVNode *Next;
} AdjVNode;typedef struct VNode {AdjVNode *FirstEdge;
} VNode, AdjList[MAXV];typedef struct {AdjList G;int VertexNum;int EdgeNum;
} LGraph;
初始化邻接表:
LGraph* CreateGraph(int VertexNum) {LGraph *Graph = (LGraph *)malloc(sizeof(LGraph));Graph->VertexNum = VertexNum;Graph->EdgeNum = 0;for (int i = 0; i < VertexNum; i++) {Graph->G[i].FirstEdge = NULL;}return Graph;
}
插入边:
void InsertEdge(LGraph *Graph, int v1, int v2) {AdjVNode *NewNode = (AdjVNode *)malloc(sizeof(AdjVNode));NewNode->AdjV = v2;NewNode->Next = Graph->G[v1].FirstEdge;Graph->G[v1].FirstEdge = NewNode;Graph->EdgeNum++;
}

通过邻接矩阵和邻接表两种方式,可以高效地存储和操作图结构,并进一步应用到图的遍历和各种图算法的实现中。


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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2024华为杯研赛E题保姆级教程思路分析

E题题目&#xff1a;高速公路应急车道紧急启用模型 今年的E题设计到图像/视频处理&#xff0c;实际上&#xff0c;E题的难度相对来说较低&#xff0c;大家不用畏惧视频的处理&#xff0c;被这个吓到。实际上&#xff0c;这个不难&#xff0c;解决了视频的处理问题&#xff0c;…

华为---代理ARP工作过程示例分析

目录 1. 示例场景 2. 基本配置 3. 配置代码 4. 测试验证 5. 抓包分析 5.1 在代理ARP环境下PC1和PC2通信分析 5.2 取消代理ARP环境下PC1和PC2通信分析 【1】取消R1路由器GE 0/0/1端口ARP代理 【2】取消R2路由器GE 0/0/1端口ARP代理 1. 示例场景 如上图所示&#xff0c;…

windows环境下配置MySQL主从启动失败 查看data文件夹中.err发现报错unknown variable ‘log‐bin=mysql‐bin‘

文章目录 问题解决方法 问题 今天在windows环境下配置MySQL主从同步&#xff0c;在修改my.ini文件后发现MySQL启动失败了 打开my.ini检查参数发现没有问题 [mysqld] #开启二进制日志&#xff0c;记录了所有更改数据库数据的SQL语句 log‐bin mysql‐bin #设置服务id&#x…

java重点学习-总结

十五 总结 https://kdocs.cn/l/crbMWc8xEZda &#xff08;总结全部的精华&#xff09; 1.面试准备 企业筛选简历规则简历编写注意事项(亮点)项目怎么找&#xff0c;学习到什么程度面试过程(表达结构、什么样的心态去找工作) 2.redis 缓存相关(缓存击穿、穿透、雪崩、缓存过期淘…

农业电商服务系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;会员管理&#xff0c;商家管理&#xff0c;商品分类管理&#xff0c;商品信息管理&#xff0c;农产品监督管理&#xff0c;助农信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页…

使用Renesas R7FA8D1BH (Cortex®-M85)实现多功能UI

目录 概述 1 系统框架介绍 1.1 模块功能介绍 1.2 UI页面功能 2 软件框架结构实现 2.1 软件框架图 2.1.1 应用层API 2.1.2 硬件驱动层 2.1.3 MCU底层驱动 2.2 软件流程图 4 软件功能实现 4.1 状态机功能核心代码 4.2 页面功能函数 4.3 源代码文件 5 功能测试 5.1…

AI字幕翻译器行业分析:前五大厂商占有大约29.5%的市场份额

AI 字幕翻译器正在彻底改变我们使用不同语言消费媒体的方式&#xff0c;使内容可以普遍访问。这些先进的技术利用机器学习和自然语言处理&#xff0c;将口语对话实时翻译成字幕。这一功能不仅打破了语言障碍&#xff0c;提升了观众的体验&#xff0c;而且还使内容创作者能够毫不…

火语言RPA流程组件介绍--获取关联元素

&#x1f6a9;【组件功能】&#xff1a;获取指定元素的父元素、子元素、相邻元素等关联信息 配置预览 配置说明 目标元素 支持T或# 默认FLOW输入项 通过自动捕获工具捕获(选择元素工具使用方法)或手动填写网页元素的css,xpath&#xff0c;指定对应网页元素作为操作目标 关联…

Arthas jvm(查看当前JVM的信息)

文章目录 二、命令列表2.1 jvm相关命令2.1.3 jvm&#xff08;查看当前JVM的信息&#xff09; 二、命令列表 2.1 jvm相关命令 2.1.3 jvm&#xff08;查看当前JVM的信息&#xff09; 基础语法&#xff1a; jvm [arthas18139]$ jvmRUNTIME …

JUC 高并发编程的入门学习

课程内容概览 什么是 JUCLock 接口线程间通信集合的线程安全多线程锁Callable 接口JUC 三大辅助类: CountDownLatch CyclicBarrier Semaphore读写锁: ReentrantReadWriteLock阻塞队列ThreadPool 线程池Fork/Join 框架CompletableFuture 1 什么是 JUC 1.1 JUC 简介 在 Java …

小tips:MySQL中如何导出表中的数据(Navicat)

1.在Navicat中找出想要导出数据的表 2.将箭头放在目的表上&#xff0c;点击右键--->点击复制表--->点击结构和数据或者仅结构&#xff08;根据需求选择需要复制的内容&#xff09;

CertiK因发现Apple Vision Pro眼动追踪技术漏洞,第6次获苹果认可

​2024年9月20日&#xff0c;头部Web3.0安全机构CertiK自豪地宣布&#xff0c;CertiK的工程师因发现Apple Vision Pro MR&#xff08;混合现实&#xff09;头显设备中的关键漏洞而获得Apple公司认可&#xff0c;这已经是Apple公司第六次公开发布对CertiK的致谢&#xff0c;Cert…

JAVA自助高效安全无人台球茶室棋牌室系统小程序源码

​探索“自助高效安全无人台球茶室棋牌室系统”的奇妙之旅 &#x1f3b1;&#x1f375;&#x1f3b2; &#x1f50d; 初见惊艳&#xff1a;未来娱乐新体验 &#x1f50d; 走进这家无人值守的台球茶室棋牌室&#xff0c;第一感觉就像是穿越到了未来&#xff01;没有繁琐的前台登…

伊犁云计算22-1 ftp 配置

1 局域网搭建好 2 yum 编译好 开干 查看有没有安装vsftpd 加载iso 光盘

如何短期提高品牌声量?说几个有效策略

在如今竞争激烈的市场环境中&#xff0c;品牌声量成为了衡量一个品牌市场影响力的关键指标。一个强大的品牌声量不仅可以增加品牌的可见度&#xff0c;还能有效提升品牌的市场竞争力。但是&#xff0c;如何有效提升品牌声量&#xff0c;成为很多企业面临的挑战。首先我们要明确…

球形包围框-Bounding Sphere-原理-代码实现

定义&#xff1a;通过一个球体包围所有点云点&#xff0c;该球体的球心和半径由点云的分布决定&#xff0c;并且球体的半径尽可能小。优点&#xff1a;计算简单&#xff0c;通常用于快速粗略估计物体的范围。缺点&#xff1a;对于不规则形状的物体&#xff0c;包围不紧密&#…

VMware tools安装

1.安装VMware tools工具 2.将压缩文件拖到桌面再解压 3. 进入终端 4.输入sudo ./vmware-install.pl 5.等待即安装成功 6.可以选择自动调整大小 7.自行调试即可

Lucene 倒排索引原理详解:深入探讨相关算法设计

引言 随着互联网的快速发展&#xff0c;数据量呈现爆炸性的增长&#xff0c;如何从海量数据中快速准确地获取所需信息成为了一项挑战。全文搜索引擎的出现极大地解决了这个问题&#xff0c;而 Lucene 正是一款优秀的开源全文搜索引擎库。本文将深入探讨 Lucene 的核心技术之一…

为人机交互保持预见性丨基于G32A1445的T-BOX应用方案

T-BOX是一种集成了通信、计算和控制功能的车载信息处理终端&#xff0c;通过车辆与云端、移动网络等进行数据交互&#xff0c;用于车、人、外部环境的互联互通&#xff0c;支持车辆定位、车载通信、远程控制、故障诊断、数据传输、紧急呼叫等功能&#xff0c;帮助车辆实现更加智…

力扣(leetcode)每日一题 2332 坐上公交的最晚时间

题目&#xff1a; 给你一个下标从 0 开始长度为 n 的整数数组 buses &#xff0c;其中 buses[i] 表示第 i 辆公交车的出发时间。同时给你一个下标从 0 开始长度为 m 的整数数组 passengers &#xff0c;其中 passengers[j] 表示第 j 位乘客的到达时间。所有公交车出发的时间互…