当前位置: 首页 > news >正文

图的邻接矩阵实现以及遍历

图的邻接矩阵实现以及遍历

文章目录

  • 图的邻接矩阵实现以及遍历

一、前言

上文图的基本概述中已经对图的存储结构进行了一个深入解析,但是具体怎么实现呢?今天我就来挑战一下~当有了图,就像对树一样,我们需要对图中的元素进行访问处理,因此需要遍历这一关键的操作,那这又该怎样实现呢?且停留片刻,相信你一定能摸清里面的门道~

二、图的遍历

同样作为非线性结构,图的遍历和树的遍历思想基本一致,其遍历可分为:深搜DFSDFSDFS),广搜BFSBFSBFS

唯一的区别:图的元素与元素之间是:m:nm:nmn,会出现重复遍历已访问过的节点。而树不会出现这个问题(往上看只有一个元素)。接下来我将对其进行深入解读~

2.1 深搜(DFSDFSDFS

2.1.1 概念

一条道走到黑。

2.1.2 思想

递归

2.1.3 过程

首先,有一个既定的原则:节点的访问由小到大V1V1V1V2V2V2​​…)。
为了防止重复遍历,需要引入visited数组,记录已经处理的节点。
如图

在这里插入图片描述

V1V1V1开始,可以到V2,V3V2,V3V2V3,由于从小到大,因此到V2V2V2V2V2V2可以到V1,V4,V5V1,V4,V5V1,V4,V5V1V1V1遍历过了,于是到V4V4V4。继续遍历,直到V5V5V5,无路可走,只能回溯,每回退一次,查看是否有遗漏的没遍历的路径,直到最后一个点。

最终结果V1−>V2−>V4−>V8−>V5−>V3−>V6−>V7V1->V2->V4->V8->V5->V3->V6->V7V1>V2>V4>V8>V5>V3>V6>V7

2.2 广搜(BFSBFSBFS

2.2.1 概念

广搜是层次遍历,就像是“水面波纹”、“病毒感染”,由里及外地探索可以触及的点(由本身的点能连接到的点)。

2.2.2 过程

但是基于遍历本身需要有先后之分,因此需要对“可触及的点”进行一个临时存储——队列。
同时在访问过程中,同样需要定义一个visited数组,记录已进入队列的(只要进过队列,就进行记录),以防止重复遍历。
每出队一个点(进行处理),就继续将其“所能接触到的点”入队。

如图

在这里插入图片描述

V1V1V1入队(标记为已访问),V1V1V1出队(处理V1V1V1),V2V2V2V3V3V3入队(标记),V2V2V2出队(处理),V4V4V4V5V5V5入队(标记),以此不断循环。

最终结果V1−>V2−>V3−>V4−>V5−>V6−>V7−>V8V1->V2->V3->V4->V5->V6->V7->V8V1>V2>V3>V4>V5>V6>V7>V8

三、邻接矩阵的实现

3.1 定义图结构

// 定义数量——便于申请时预留空间
#define MaxNodeNum 20
// 定义一个足够大的值(表示边的权值)
#define INF		   1E4
// 邻接矩阵的顶点结构
typedef struct
{int no;			// 顶点编号char *show;		// 显示顶点信息
} MatrixVertex;
// 表示边
typedef int MatrixEdge;
// 图的邻接矩阵表示法
typedef struct
{MatrixVertex vex[MaxNodeNum];					// 点集(一维数组)int NodeNum;									// 对数量进行限制MatrixEdge edges[MaxNodeNum][MaxNodeNum];		// 边集(矩阵)int edgeNum;									// 边的数量int directed;									// 表示是否有向
} MGraph;

3.2 初始化

初始化点集合边集
如图

在这里插入图片描述

// 初始化图
void initMGraph(MGraph *graph, char *names[], int num, int directed, int edgeValue)
{graph->directed = directed;graph->nodeNum = num;			// 自己定义好的graph->edgeNum = 0;				// 边需要自己建立// 初始化点集memset(graph->vex, 0, sizeof(graph->vex));// 初始化边集,当节点数量为n时,边的最大数量为n^2(每一个顶点都可以和其他任意的顶点建立边,// 包括它自己)memset(graph->edges, 0, sizeof(MatrixEdge) * MaxNodeNum * MaxNodeNum);for(int i = 0; i < num; ++i){// 初始化顶点信息graph->vex[i].no = i;graph->vex.show = names[i];// 初始化边for(int j = 0; j < num; ++j){graph->edges[i][j] = edgeValue;		// 二维数组中存在的值(表示边的连接情况)}}
}

3.3 添边

  • 判断边的合法性
  • 填充矩阵edgeValue

如图(最终)

在这里插入图片描述

// 判断边
static int isEdge(int weight)
{if(weight > 0 && weight < INF){return 1;}return 0;
}
// 添加边
void addMGraphEdge(MGraph *graph, int x, int y, int w)
{// 判断横坐标是否合法if(x < 0 || x > graph->nodeNum){return;}// 判断纵坐标是否合法if(y < 0 || y > graph->nodeNum){return;}if(!isEdge(graph->edges[x][y])){graph->edges[x][y] = w;if(graph->directed == 0){// 只有当图为无向图时,才需要存储这个信息graph->edges[y][x] = w;}graph->edgeNum++;}
}

3.4 访问

easy~

void visitMGraphNode(MatrixVertex *node)
{printf("\t%s", node->show);
}

3.5 深搜

  • 访问顶点,标记顶点
  • 从上述顶点出发,继续遍历可访问的顶点(按从小到大的顺序),循环上述过程

如图

在这里插入图片描述

// 定义已访问的空间(全局变量,BFS也会用到)
static int MGraphVisited[MaxNodeNum];
// 深搜
void DFS_MGraph(MGraph *graph, int v)
{// 访问visitMGraphNode(graph->vex[v]);// 标记MGraphVisited[v] = 1;for(int i = 0; i < graph->nodeNum; ++i){if(isEdge(graph->edges[v][i]) && MGraphVisited[i] == 0){DFS_MGraph(graph, i);	// 递归}}
}

3.6 广搜

  • 定义一个临时队列
  • 入队顶点,标记为已访问
  • 出队顶点,访问,(从该顶点出发)入队可访问的顶点
  • 循环上述过程

如图

在这里插入图片描述

// 注意:当同时调用DFS和BFS时,因为两种遍历都需要用到标记访问的数组,因此在中间需要有一个清零的过程
void initVisited()
{memset(MGraphVisited, 0, sizeof(MGraphVisited));
}
// 广搜
void BFS_MGraph(MGraph *graph, int v)
{int que[MaxNodeNum];                    		// 定义临时队列int rear = 0, front = 0; int cur;       		// 定义尾巴,头,要访问的当前顶点rear = (rear + 1) % MaxNodeNum;         		// 实现尾指针的循环移动,队尾先加que[rear] = v;									// 入队MGraphVisited[v] = 1;							// 入队之后就进行标记while (front != rear){front = (front + 1) % MaxNodeNum;   		// 出队cur = que[front];                   		// 取出来visitMGraphNode(&graph->vex[cur]);			// 访问for (int i = 0; i < graph->nodeNum; ++i)	// 继续入队可遍历的节点{if (isEdge(graph->edges[cur][i]) && !MGraphVisited[i]){rear = (rear + 1) % MaxNodeNum;que[rear] = i;MGraphVisited[i] = 1;}}}
}

小结

本篇主要以邻接矩阵的实现为主,下篇将会迎来邻接表哦~期待inginging

希望各位不吝赐教~

http://www.dtcms.com/a/554028.html

相关文章:

  • 伟淼科技发布11月营销前瞻:解码 “温暖狂欢感恩” 增长公式
  • 前端学习css
  • 外链推广网站都有哪些网站首页分辨率
  • 网站查询域名解析用extjs做的网站
  • 【计算机网络】NAT技术深度解析:从原理到NAPT实现的工作机制
  • 外设模块学习(10)——红外避障模块(STM32)
  • 60 d3.js 不能正确展示节点连线, 以及一个基础的demo
  • 优质网站建设是哪家北京论坛网站建设
  • 黑马商城day8-ES01
  • 创意网站建设公司阿里云宝塔面板一键安装wordpress
  • F043 vue+flask天气预测可视化系统大数据(浅色版)+机器学习+管理端+爬虫+超酷界面+顶级可视化水平
  • 电脑无法识别WiFi 7路由器的解决方式
  • 海南网站推广微商目前十大火爆产品
  • Nestjs框架: 微服务架构实践与技术选型指南
  • 网络请求完整指南 - 从原理到实践
  • PHP网站建设项目经验动态wordpress动态主题
  • 企业网站建设项目描述saas小程序开发
  • 各大门户网站怎么做推广如何做网站 优帮云
  • Python在云计算中的应用:AWS Lambda函数实战
  • Spring Cloud OpenFeign进行服务间调用时,传递自定义的请求头信息及报错解决
  • 基于单片机的 AI 智能快递柜设计与实现
  • 【医学影像 AI】视网膜图像多类别分割中的“段内误分类”
  • python3.13安装教程(附安装包),【2025】python3.13安装图文教程
  • 深圳专业建站多少钱线上渠道推广
  • ROS开发中`laser_scan_matcher`节点启动失败问题的分析与解决
  • 南昌装修网站建设菠菜网站的代理怎么做
  • c++调用客户端库与kafka交互
  • 用Liunx service方式管理SuperMap iServer
  • 邢台网站设计哪家专业wordpress主题添加后台设置选项
  • 京东网站建设的策划书如何做120急救网站