数据结构+图的基本应用

news2025/1/12 23:17:25

一、问题描述

求有向图的简单路径 编写一个程序,设计相关算法完成以下功能。

(1)输出如图所示的有向图 G 从顶点 5 到顶点 2 的所有简单路径。

(2)输出如图所示的有向图 G 从顶点 5 到顶点 2 的所有长度为 3 的简单路径。

(3)输出如图所示的有向图 G 从顶点 5 到顶点 2 的所有最短路径。

二、问题解决

#include <stdio.h> 
#include <malloc.h> #define INF 32967 //定义∞ 
#define MAXV 100 //最大顶点个数 
 
typedef char InfoType; 
typedef struct 
{ 
 int no; //顶点编号 
 InfoType info; //顶点信息 
}VertexType; //顶点类型 
 
typedef struct ArcNode 
{ 
 int adjvex; //该边的邻接点编号 
 struct ArcNode *nextarc; //指向下一条边的指针 
 int weight; //该边的相关信息,如权值(用整型
表示) 
}ArcNode; //边结点类型 
 
typedef struct VNode 
{ 
 InfoType info; //顶点其他信息 
 int cnt; //存放顶点入度,仅用于拓扑排序 
 ArcNode *firstarc; //指向第一条边 
}VNode; //邻接表结点类型 
 
typedef struct 
{ 
 VNode adjlist[MAXV]; //邻接表头结点数组 
 int n; //图中顶点数 
 int e; //图中边数 
}AdjGraph; //完整的图邻接表类型 
 
void CreateAdj(AdjGraph *&G, int A[MAXV][MAXV], int n, int e) 
{ 
 int i, j; 
 ArcNode *p; 
 
 G = (AdjGraph *)malloc(sizeof(AdjGraph)); 
 for(i = 0; i < n; i++) //给邻接表
中所有头结点的指针域置初值 NULL  { 
 G->adjlist[i].firstarc = NULL; 
 } 
 
 for(i = 0; i < n; i++) //检查邻接
矩阵中的每个元素 
 { 
 for(j = n - 1; j >= 0; j--) 
 { 
 if(A[i][j] != 0 && A[i][j] != INF) //存在一条
边 
 { 
 p = (ArcNode *)malloc(sizeof(ArcNode)); //创建一个结
点 p 
 p->adjvex = j; //邻接点编
号 
 p->weight = A[i][j]; //边的权重 
 p->nextarc = G->adjlist[i].firstarc; //采用头插
法插入结点 p 
 G->adjlist[i].firstarc = p; 
 } 
 } 
 } 
 G->n = n; 
 G->e = e; 
} 
 
void DestroyAdj(AdjGraph *&G) 
{ 
 ArcNode *pre, *p; 
 
 for(int i = 0; i < G->n; i++) 
 { 
 pre = G->adjlist[i].firstarc; //pre 指向第
i 个单链表的首结点 
 if(pre != NULL) 
 { 
 p = pre->nextarc; 
 while(p != NULL) //释放第 i
个单链表的所有边结点  { 
 free(pre); 
 pre = p; 
 p = p->nextarc; 
 } 
 free(pre); 
 } 
 } 
 free(G); //释放头结点数组 
} 
 
//深度优先遍历 
int visited[MAXV]; //全局数组 
 void allPath(AdjGraph *G, int u, int v, int path[], int d) 
{ 
 ArcNode *p; 
 int i; 
 int w; 
 d++; //路径长度增 1 
 path[d] = u; //当前顶点添加到路径中 
 visited[u] = 1; //置已访问标记 
 if(u == v && d > 0) //找到终点 
 { 
 for(i = 0; i <= d; i++) 
 printf("%3d", path[i]); 
 printf("\n"); 
 } 
 p = G->adjlist[u].firstarc; //p 指向顶点 u 的第一个相邻点 
 while(p != NULL) 
 { 
 w = p->adjvex; //w 为 u 的相邻点编号 
 if(visited[w] == 0) //若该顶点未标记访问,则递归访问之 
 allPath(G, w, v, path, d); 
 p = p->nextarc; //找 u 的下一个相邻点 
 } 
 visited[u] = 0; //取消访问标记,以使该顶点可重新使
用 
} 
 
  void allPath_len2(AdjGraph *G, int u, int v, int len, int path[], 
int d) 
{ 
 int i; 
 int w; 
 ArcNode *p; //边结点类型指针 
 visited[u] = 1; //置已访问标记 
 d++; //路径长度增 1 
 path[d] = u; //将当前顶点添加到路径中 
 if(u == v && d == len) //满足条件,输出一条路径 
 { 
 for(i = 0; i <= d; i++) 
 printf("%3d", path[i]); 
 printf("\n"); 
 } 
 p = G->adjlist[u].firstarc; //p 指向顶点 u 的第一个相邻点 
 while(p != NULL) 
 { 
 w = p->adjvex; //w 为顶点 u 的相邻点编号 
 if(visited[w] == 0) //若该顶点未标记访问,则递归访问之 
 allPath_len2(G, w, v, len, path, d); 
 p = p->nextarc; //找 u 的下一个相邻点 
 } 
 visited[u] = 0; //取消访问标记,以使该顶点可重新使
用 
} 
 
//广度优先遍历 
int short_path(AdjGraph *G, int u, int v, int path[]) 
{ 
 struct 
 { 
 int vno; //当前顶点编号 
 int level; //当前顶点的层次 
 int parent; //当前顶点的双亲结点在队列中的下标 
 }qu[MAXV]; //定义顺序非循环队列 
 int qu_front = -1, qu_rear = -1, k, lev, i, j; 
 ArcNode *p; 
 visited[u] = 1; 
 qu_rear++; //顶点 u 已访问,将其入队  qu[qu_rear].vno = u; 
 qu[qu_rear].level = 0; 
 qu[qu_rear].parent = -1; 
 while(qu_front < qu_rear) //队非空循环 
 { 
 qu_front++; 
 k = qu[qu_front].vno; //出队顶点 k 
 lev = qu[qu_front].level; 
 if(k == v) //若顶点 k 为终点 
 { 
 i = 0; 
 j = qu_front; 
 while(j != -1) 
 { 
 path[lev - i] = qu[j].vno; 
 j = qu[j].parent; 
 i++; 
 } 
 return lev; //找到顶点 v,返回其层次 
 } 
 p = G->adjlist[k].firstarc;//p 指向顶点 k 的第一个相邻点 
 while(p != NULL) //依次搜索 k 的相邻点 
 { 
 if(visited[p->adjvex] == 0)//若未访问过 
 { 
 visited[p->adjvex] = 1; 
 qu_rear++; 
 qu[qu_rear].vno = p->adjvex;//访问过的相邻点进队 
 qu[qu_rear].level = lev + 1; 
 qu[qu_rear].parent = qu_front; 
 } 
 p = p->nextarc; //找到顶点 k 的下一个相
邻点 
 } 
 } 
 
 return -1; 
} 
 
 int main() 
{ 
 int i, j; 
 int u = 5, v = 2, len = 3; 
 int path[MAXV]; 
 AdjGraph *G; 
 int A[MAXV][MAXV] = { 
 {0, 1, 0, 1, 0, 0}, 
 {0, 0, 1, 0, 0, 0}, 
 {1, 0, 0, 0, 0, 1}, 
 {0, 0, 1, 0, 0, 1}, 
 {0, 0, 0, 1, 0, 0}, 
 {1, 1, 0, 1, 1, 0} 
 }; 
 int n = 6; //顶点数 
 int e = 12; //边数 
 CreateAdj(G, A, n, e); 
 printf("(1)从顶点%d 到%d 的所有路径:\n", u, v); 
 for(i = 0; i < n; i++) 
 visited[i] = 0; 
 allPath(G, u, v, path, -1); 
 printf("(2)从顶点%d 到%d 的所有长度为%d 路径:\n", u, v, len); 
 allPath_len2(G, u, v, len, path, -1); 
 printf("(3)从顶点%d 到%d 的最短路径:\n", u, v); 
 for(i = 0; i < n; i++) 
 visited[u] = 0; 
 j = short_path(G, u, v, path); 
 for(i = 0; i <=j; i++) 
 printf("%3d", path[i]); 
 printf("\n"); 
 DestroyAdj(G); 
 return 0; 
} 

三、代码分析

1、输出有向图 G 从顶点 5 到顶点 2 的所有简单路径:采用从顶点 u 出发的回 溯深度优先搜索方法,当搜索到顶点 v 时输出路径 path[0..d],然后继续回溯 查找其他路径。

2、输出有向图 G 从顶点 5 到顶点 2 的所有长度为 3 的简单路径:采用从顶点 u 出发的回溯深度优先搜索方法,每搜索一个新顶点,路径长度增 1,若搜索 到顶点 v 且 d 等于 len,则输出路径 path[0..d],然后继续回溯查找其他路 径。

3、输出有向图 G 从顶点 5 到顶点 2 的所有最短路径:采用从顶点 u 出发广度 优先搜索方法,当搜索到顶点 v 时,在队列中找出对应的路径。由广度优先搜 索可知,找到的路径一定是最短路径。

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

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

相关文章

Qt编译配置OpenCV+opencv_contrib(使用cmake)

本文使用环境 OpenCV: 4.7.0 cmake: 3.30.2 Qt: 5.12.1一、配置环境变量 安装好OpenCV、Qt、cmake后&#xff0c;应配置好一下环境变量&#xff1a; 二、编译OpenCV 打开cmake&#xff0c;编译的源码路径选择opencv文件夹中的sources目录&#xff0c;在opencv文件夹下新建一…

代码随想录 day 38 动态规划

第九章 动态规划part06 322. 零钱兑换 如果求组合数就是外层for循环遍历物品&#xff0c;内层for遍历背包。 如果求排列数就是外层for遍历背包&#xff0c;内层for循环遍历物品。 这句话结合本题 大家要好好理解。 视频讲解&#xff1a;https://www.bilibili.com/video/BV14K…

【自用】Python爬虫学习(六):通过m3u8文件下载ts文件并合并为.mp4文件

Python爬虫学习&#xff08;六&#xff09; 下载视频&#xff08;简单版&#xff09;的步骤介绍第一步&#xff1a;在网页上找到.m3u8文件第二步&#xff1a;通过.m3u8文件下载对应的.ts视频文件第三步&#xff1a;依据.m3u8文件合并.ts文件为一个.mp4文件 下载视频&#xff08…

stm32智能颜色送餐小车(oled显示压力传感器重量)

大家好啊&#xff0c;我是情谊&#xff0c;今天我们来介绍一下我最近设计的stm32产品&#xff0c;我们在今年七月份的时候参加了光电设计大赛&#xff0c;我们小队使用的就是stm32的智能送餐小车&#xff0c;虽然止步于省赛&#xff0c;但是还是一次成长的经验吧&#xff0c;那…

PyQt编程快速上手

Python GUI安装 GUI就是图形用户界面的意思&#xff0c;在Python中使用PyQt可以快速搭建自己的应用&#xff0c;使得自己的程序看上去更加高大上&#xff0c;学会GUI编程可以使得自己的软件有可视化的结果。 如果你想用Python快速制作界面&#xff0c;可以安装PyQt&#xff1a…

Linux云计算 |【第二阶段】NETWORK-DAY6

主要内容&#xff1a; 企业网络综合项目分析、大型企业网络搭建 项目案例1 一家网络公司&#xff0c;有若干服务器&#xff0c;通过NAT技术将业务服务器与Internet互联&#xff1b;已有技术&#xff1a; ① 默认路由&#xff1a;实现到互联网数以万计网络访问的简化配置&…

Elasticsearch自动补全功能实践与Java API应用

Elasticsearch是一个强大的搜索引擎&#xff0c;它不仅支持全文搜索&#xff0c;还提供了自动补全功能&#xff0c;可以显著提升用户体验。自动补全功能允许用户在输入查询时实时显示建议项&#xff0c;帮助用户快速找到所需信息。本文将介绍如何使用Elasticsearch的RestHighLe…

配置Google API,用JavaScript和Python读取Google sheet里的数据

[发布时间是2024年8月。技术流程可能会存在一些变动] 源代码可以参考&#xff1a;victorspaceRMW/Read-Google-Sheet-with-API: The source code to read the Google Sheet with Google cloud API (github.com) 开头提醒一下各位公司&#xff0c;国内包括腾讯云华为云阿里云&…

echarts使图表组件根据屏幕尺寸变更而重新渲染大小

效果图&#xff1a; 通过 window.addEventListener(resize, this.resizeChart); 实现 完整代码&#xff1a; <template><div class"dunBlock"><div class"char2" id"char2" ref"chart"></div></div…

《光与夜之恋》3D建模含量超标,纯炫技还是释放新信号?

继叠纸的《恋与深空》之后&#xff0c;腾讯的《光与夜之恋》也卷起3D技术了。 《光与夜之恋》即将在8月12日上线的限定活动“大漠归墟”最新PV及男主六星卡面释出&#xff0c;相对于褒贬不一、引起争论的卡面美术&#xff0c;PV中的3D建模倒是收获了玩家的集体好评。 “大漠归…

读零信任网络:在不可信网络中构建安全系统18零信任代理

1. 零信任代理 1.1. 零信任代理是应用级代理服务器&#xff0c;用来保护零信任网络&#xff0c;它是处理认证、授权以及加密的基础设施 1.2. 零信任代理分为反向代理和前向代理两种工作模式 1.2.1. 运行时可以同时采用这两种工作模式&#xff0c;也可以只采用其中的一种 1.2…

libcurl8.9.1 上传json

在postman中 PUT----》body----》raw----》json 结构体定义&#xff1a; #define MAX_ARRAY_SIZE 5*1024*1024struct SMART_DATA_CACHE {char* buf;long dwTotalLen;SMART_DATA_CACHE(){dwTotalLen 0;buf nullptr;while (!buf) {try {buf new char[MAX_ARRAY_SIZE];}c…

C++:有序关联容器set

什么是有序关联容器 (1)顺序容器&#xff0c;容器中的元素是按它们在容器中的位置来顺序保存和访问的(可以理解是数组) (2)顺序容器有array、vector、deque、list、forward_list、string等 (3)关联容器中的元素是按关键字来保存和访问的&#xff0c;关联的意思就是关键字&…

STM32-外部中断-AFIO-串口-串口通信-串口中断(空闲中断和接收中断)-printf移植-ADC数模转换-初始化和读取光敏电阻AO

常用的中断包括外部中断、串口中断、定时器中断&#xff1b; 1、外部中断&#xff1a; 引脚复用按钮导致的外部中断&#xff1a; 注意&#xff1a;初始化引脚&#xff0c;添加引脚和EXTI输入线的映射&#xff1b;使用外部引脚的中断时需要使用AFIO映射&#xff1b; 操作步骤&…

如何获取android的SHA1或SHA256

在使用地图类的功能时&#xff0c;例如百度地图或者高德地图&#xff0c;会需要在开发者平台里填写SHA1或SHA256的指纹密钥&#xff0c;很多开发者小伙伴还不知道如何获取。当然关于如何获取android的SHA1或SHA256&#xff0c;网络上进行搜索已经有很多图文教程了&#xff0c;本…

mfc140u.dll丢失的科学修复手段,简单又方便的mfc140u.dll修复

遇到 "缺失 mfc140u.dll 文件" 的提示时可能会让你疑惑&#xff0c;但不用担心。这个文件是 Microsoft Visual C 2015 的重要组成部分&#xff0c;对运行特定程序非常关键。幸运的是&#xff0c;解决这一问题并不难。本文将简单指导你如何恢复或修复丢失的 mfc140u.d…

多台PC网络ADB连接同一台RK3399 Android7.1.2设备

在RK3399 Android7.1.2上面&#xff0c;进行网络ADB调试时&#xff0c;如果多台电脑连接同一台Android设备&#xff0c;第一台连接上的能正常操作&#xff0c;之后连接的看到设备状态为OFFLINE&#xff0c;分析了下ADBD相关代码&#xff0c;发现在ACCEPT Client的时候没有区分别…

设计师必备:2024最新PDF转CAD软件盘点

随着科技的飞速发展&#xff0c;设计师们不再受限于传统的设计流程&#xff0c;可以利用一些新欣的工具来提升工作效率、优化工作流程的新工具。其中&#xff0c;PDF转CAD工具成为了设计行业的一大热门话题。面对海量的数据和复杂的设计需求&#xff0c;一款高效、精准的PDF转C…

11、MySQL-SQL优化

目录 1、插入数据 1.1、批量插入 1.2、手动提交事务 1.3、主键顺序插入 1.4、大批量插入数据 2、主键优化 2.1 页分裂 2.2 主键顺序插入 2.3 主键乱序插入 2.4 页合并 2.5 主键的设计原则 3、order by优化 4、group by优化 5、limit优化 6、count优化 6.1 coun…

【Bifrost】ubuntu24.04 远程构建及clion设置编码风格google

Bifrost 构建通过clion 远程到ubuntu24.04 构建感觉是不认识这种写法,这种至少是c++11 fix : 修改absl 的构建cmakelist,明确c++17 好像还是不行error: ‘uint8_t’ was not declared in this scope加入:#include <stdint.h>可以解决一部分。那么,这种呢?/home/zha…