图用邻接表表示的深度优先和广度优先遍历

邻接表表示法进行深度优先遍历的示例代码:

#include <stdio.h>
#include <stdlib.h>#define MAX_VERTEX_NUM 100// 边表节点结构体
typedef struct ArcNode {int adjvex;                 // 邻接顶点下标struct ArcNode* nextarc;    // 指向下一个邻接顶点的指针
} ArcNode;// 顶点表结构体
typedef struct VNode {int data;                   // 顶点数据ArcNode* firstarc;          // 指向第一个邻接顶点的指针
} VNode, AdjList[MAX_VERTEX_NUM];// 图结构体
typedef struct {AdjList vertices;           // 邻接表int vexnum, arcnum;         // 顶点数、边数
} ALGraph;// 初始化图
void InitGraph(ALGraph* G, int vexnum) {G->vexnum = vexnum;G->arcnum = 0;for (int i = 0; i < vexnum; i++) {G->vertices[i].data = i;    // 顶点数据默认为下标G->vertices[i].firstarc = NULL;}
}// 添加边
void AddEdge(ALGraph* G, int v1, int v2) {ArcNode* arc1 = (ArcNode*)malloc(sizeof(ArcNode));arc1->adjvex = v2;arc1->nextarc = G->vertices[v1].firstarc;G->vertices[v1].firstarc = arc1;ArcNode* arc2 = (ArcNode*)malloc(sizeof(ArcNode));arc2->adjvex = v1;arc2->nextarc = G->vertices[v2].firstarc;G->vertices[v2].firstarc = arc2;G->arcnum++;
}// 深度优先遍历递归函数
void DFS(ALGraph* G, int v, int* visited) {visited[v] = 1;     // 标记当前顶点为已访问printf("%d ", G->vertices[v].data);ArcNode* arc = G->vertices[v].firstarc;while (arc != NULL) {if (visited[arc->adjvex] == 0) {DFS(G, arc->adjvex, visited);   // 递归访问邻接顶点}arc = arc->nextarc;}
}// 深度优先遍历
void DFSTraverse(ALGraph* G) {int visited[MAX_VERTEX_NUM] = { 0 };    // 访问标记数组,初始化为0for (int v = 0; v < G->vexnum; v++) {if (visited[v] == 0) {DFS(G, v, visited);     // 从未访问的顶点开始进行深度优先遍历}}
}int main() {ALGraph G;int vexnum = 5;     // 图的顶点数InitGraph(&G, vexnum);AddEdge(&G, 0, 1);AddEdge(&G, 0, 2);AddEdge(&G, 1, 3);AddEdge(&G, 2, 4);DFSTraverse(&G);return 0;
}

其中顶点表使用了数组 AdjList,每个顶点表项存储了顶点的数据和指向第一个邻接顶点的指针。边表节点使用了结构体 ArcNode,存储了邻接顶点的下标和指向下一个邻接顶点的指针。
DFS 函数是一个递归函数,用于从给定顶点开始进行深度优先遍历。它首先将当前顶点标记为已访问,并输出顶点的数据。然后,遍历当前顶点的邻接表,对于每个未被访问过的邻接顶点,递归调用 DFS 函数进行遍历。
DFSTraverse 函数用于遍历图中所有顶点,并对未访问过的顶点调用 DFS 函数进行深度优先遍历。

广度优先遍历(Breadth-First Search,BFS)是一种图遍历算法,它以广度优先的顺序遍历图的所有节点。下面是使用邻接表表示图,并进行广度优先遍历的示例代码:

#include <stdio.h>
#include <stdlib.h>#define MAX_VERTEX_NUM 100// 边表节点结构体
typedef struct ArcNode {int adjvex;                 // 邻接顶点下标struct ArcNode* nextarc;    // 指向下一个邻接顶点的指针
} ArcNode;// 顶点表结构体
typedef struct VNode {int data;                   // 顶点数据ArcNode* firstarc;          // 指向第一个邻接顶点的指针
} VNode, AdjList[MAX_VERTEX_NUM];// 图结构体
typedef struct {AdjList vertices;           // 邻接表int vexnum, arcnum;         // 顶点数、边数
} ALGraph;// 初始化图
void InitGraph(ALGraph* G, int vexnum) {G->vexnum = vexnum;G->arcnum = 0;for (int i = 0; i < vexnum; i++) {G->vertices[i].data = i;    // 顶点数据默认为下标G->vertices[i].firstarc = NULL;}
}// 添加边
void AddEdge(ALGraph* G, int v1, int v2) {ArcNode* arc1 = (ArcNode*)malloc(sizeof(ArcNode));arc1->adjvex = v2;arc1->nextarc = G->vertices[v1].firstarc;G->vertices[v1].firstarc = arc1;ArcNode* arc2 = (ArcNode*)malloc(sizeof(ArcNode));arc2->adjvex = v1;arc2->nextarc = G->vertices[v2].firstarc;G->vertices[v2].firstarc = arc2;G->arcnum++;
}// 广度优先遍历
void BFSTraverse(ALGraph* G, int v) {int visited[MAX_VERTEX_NUM] = { 0 };    // 访问标记数组,初始化为0int queue[MAX_VERTEX_NUM];              // 存储待访问顶点的队列int front = 0;                          // 队列头指针int rear = 0;                           // 队列尾指针visited[v] = 1;     // 标记当前顶点为已访问printf("%d ", G->vertices[v].data);queue[rear++] = v;  // 将当前顶点入队while (front < rear) {int w = queue[front++];     // 从队列中取出一个顶点ArcNode* arc = G->vertices[w].firstarc;while (arc != NULL) {int adjvex = arc->adjvex;if (visited[adjvex] == 0) {visited[adjvex] = 1;            // 标记邻接顶点为已访问printf("%d ", G->vertices[adjvex].data);queue[rear++] = adjvex;         // 将邻接顶点入队}arc = arc->nextarc;}}
}int main() {ALGraph G;int vexnum = 5;     // 图的顶点数InitGraph(&G, vexnum);AddEdge(&G, 0, 1);AddEdge(&G, 0, 2);AddEdge(&G, 1, 3);AddEdge(&G, 2, 4);BFSTraverse(&G, 0);return 0;
}

BFSTraverse 函数中,我们使用一个队列来存储待访问的顶点。初始时,将起始顶点入队,并将其标记为已访问。然后,从队列中取出一个顶点进行处理,输出其数据,并将其所有未访问的邻接顶点入队并标记为已访问。重复这个过程,直到队列为空。这样就实现了广度优先遍历。
main 函数中,首先初始化图并添加边。然后,调用 BFSTraverse 函数以开始广度优先遍历。

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

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

相关文章

数组指定部分逆序重放

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…

pgsql的jsonb相关处理及样例

目录 1、某个字段中包含目标list中的全部使用>&#xff1a; 2、某个字段中包含目标list中任意值使用?|&#xff1a; 3、其他操作样例&#xff1a; 1、某个字段中包含目标list中的全部使用>&#xff1a; SELECT * FROM "public"."t_a" WHERE a::j…

ubuntu 20.04 docker prometheus

ubuntu 20.04 docker https://docs.docker.com/engine/install/ubuntu/ Ubuntu20.04下部署linux资源监控平台&#xff08;docker部署&#xff09;grafanaprometheusnode_exporter&#xff08;docker离线包&#xff09; https://blog.csdn.net/deer_cui/article/details/1340208…

基于ssm物资进销存论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本货物进销管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

day15-动画和路由过渡和切换

&#x1f4da; 目录 介绍介绍 AnimationCurveAnimationControllerTween监听动画 自定义路由切换动画Hero飞行动画交织动画动画切换组件 AnimatedSwitcherAnimatedSwitcher封装 动画过渡组件 本文学习和引用自《Flutter实战第二版》&#xff1a;作者&#xff1a;杜文 1. 介绍 …

C#中HttpWebRequest的用法

前言 HttpWebRequest是一个常用的类&#xff0c;用于发送和接收HTTP请求。在C#中使用HttpWebRequest可以实现各种功能&#xff0c;包括发送GET和POST请求、处理Cookie、设置请求头、添加参数等。本文将深入介绍HttpWebRequest的用法&#xff0c;并给出一些常见的示例。 目录 前…

Java面试总结——集合篇

摘自javaguide的集合总体框架图&#xff1a; List, Set, Queue, Map 的区别 List&#xff1a;底层基于object[]数组&#xff0c;存储的元素有序、可重复。 Set&#xff1a;底层基于HashMap实现&#xff0c;存储的元素无序&#xff0c;不可重复。 Queue&#xff1a;单…

科研院校和研究所都在用功率放大器做哪些实验

科研院校和研究所在科研工作中常常使用功率放大器进行实验。功率放大器是一种电子设备&#xff0c;其主要功能是将输入信号的功率增加到预定的输出功率水平&#xff0c;并保持信号的波形不失真。它在各个学科领域都有广泛的应用&#xff0c;包括通信、无线电、雷达、生物医学等…

vue3 使用<script lang=“ts“ setup>加上lang=“ts“后编译错误

报错信息 报错原因 加上了langts解决 下载typescript和loader npm install typescript ts-loader --save-dev配置vue.config.js 添加下面的代码 configureWebpack: { resolve: { extensions: [".ts", ".tsx", ".js", ".json"] }…

Axure中继器的使用

一.中继器介绍 在Axure中&#xff0c;中继器&#xff08;Relays&#xff09;是一种功能强大的元件&#xff0c;可以用于创建可重复使用的模板或组件。中继器允许您定义一个主要的模板&#xff0c;并在页面中重复使用该模板的实例。以下是中继器的作用和优缺点&#xff1a; 作…

Wireshark在移动网络中的应用

第一章&#xff1a;Wireshark基础及捕获技巧 1.1 Wireshark基础知识回顾 1.2 高级捕获技巧&#xff1a;过滤器和捕获选项 1.3 Wireshark与其他抓包工具的比较 第二章&#xff1a;网络协议分析 2.1 网络协议分析&#xff1a;TCP、UDP、ICMP等 2.2 高级协议分析&#xff1a;HTTP…

2023 英特尔On技术创新大会直播 |我感受到的AI魅力

文章目录 前言英特尔技术创新大会 的来历芯生无限 赋能AI创新后记 前言 近年来&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff09;的应用与发展呈现出爆发式增长的态势&#xff0c;成为科技领域最为引人注目的热门话题之一。作为全球领先的半导体公司&…

workflow系列教程(5-1)HTTP Server

往期教程 如果觉得写的可以,请给一个点赞关注支持一下 观看之前请先看,往期的博客教程,否则这篇博客没办法看懂 workFlow c异步网络库编译教程与简介 C异步网络库workflow入门教程(1)HTTP任务 C异步网络库workflow系列教程(2)redis任务 workflow系列教程(3)Series串联任务流…

Boto3按名字搜索AWS Image并返回Image的相关参数 (Python)

文章目录 小结问题及解决参考 小结 本文记录使用Python脚本和Boto3按名字搜索AWS Image并返回AWS Image的相关参数。 问题及解决 记得操作之前拿到相应的权限&#xff1a; export AWS_ACCESS_KEY_ID"xxxxxxxxxxxxxxxxxxxxxxxxxx"export AWS_SECRET_ACCESS_KEY&qu…

《Linux C编程实战》笔记:进程操作之ID,优先级

获得进程ID getpid函数 这个函数都用了很多次了&#xff0c;看一下定义和例子就行了 #include<sys/types.h> #include <unistd.h> pid_t getpid(void); 示例程序1 #include<cstdlib> #include<malloc.h> #include<cstring> #include <cs…

Tomcat (Linux系统)详解全集

点击标题进入对应模块学习&#xff0c;你也可以完全拿捏Tomcat&#xff01; 1 Tomcat及JDK下载安装&#xff08;Linux系统&#xff09; 2 Tomcat目录介绍 3 Tomcat的启动关闭及日志说明 4 完美解决Tomcat启动慢的三种方法 5 Tomcat管理功能使用 6 Tomcat主配置文件&#xff08;…

SSM整合实战(Spring、SpringMVC、MyBatis)

五、SSM整合实战 目录 一、SSM整合理解 1. 什么是SSM整合&#xff1f;2. SSM整合核心理解五连问&#xff01; 2.1 SSM整合涉及几个IoC容器&#xff1f;2.2 每个IoC容器盛放哪些组件&#xff1f;2.3 IoC容器之间是什么关系&#xff1f;2.4 需要几个配置文件和对应IoC容器关系&…

Python工程部署到Linux云服务器

安装python # 更新源 sudo yum install epel-release# 更新源 sudo yum update# 安装python3 sudo yum install python3# 验证 python3 -V安装pip # 安装 sudo yum install python3-pip# 升级 python3 -m pip install --upgrade pip安装virtualenv、virtualenvwrapper sudo …

Ubuntu中常用的基本操作指令及其功能

文件和目录操作&#xff1a; ls&#xff1a;列出当前目录下的文件和子目录。cd&#xff1a;切换目录。例如&#xff0c;cd /home/user 切换到 /home/user 目录。pwd&#xff1a;显示当前工作目录。mkdir&#xff1a;创建新目录。例如&#xff0c;mkdir new_directory 创建一个名…

2.vue学习(8-13)

文章目录 8.数据绑定9.el与data的2种写法10.理解mvvm11.object.defineProperty12. 理解数据代理13 vue中的数据代理 8.数据绑定 单向数据绑定就是我们学的v-bind的方式&#xff0c;vue对象变了&#xff0c;页面才变。但是页面变了&#xff0c;vue对象不会变。 双向数据绑定需要…