李春葆《数据结构》-课后习题代码题
一:假设不带权有向图采用邻接矩阵 g 存储,设计实现以下功能的算法:
(1)求出图中每个顶点的入度。
void indegree(MatGraph g){int i,j,n;printf("各个顶点的入度:\n");for(int j=0;j<g.n;j++){n=0;for(int i=0;i<g.n;i++){if(g.edges[i][j]!=0){n++;}}printf(" 顶点%d:%d\n",j,n);}
}
(2)求出图中每个顶点的出度。
void outdegree(MatGraph g){int i,j,n;printf("各个顶点的出度:\n");for(int i=0;i<g.n;i++){n=0;for(int j=0;j<g.n;j++){if(g.edges[i][j]!=0){n++;}}printf(" 顶点%d:%d\n",i,n);}
}
(3)求出图中出度为0的顶点数。
void zeroOutdegree(MatGraph g){int i,j,n;printf("出度为0的顶点:\n");for(int i=0;i<g.n;i++){n=0;for(int j=0;j<g.n;j++){if(g.edges[i][j]!=0){n++;}} if(n==0)printf("%d\n",i);}printf("\n");
}
二:假设不带权有向图采用邻接表 G 存储,设计实现以下功能的算法:
(1)求出图中每个顶点的入度。
void indegree(AdjGraph *g){ArcNode *p;int A[MAX],i;for(i=0;i<g->n;i++){A[i]=0;}for(i=0;i<g->n;i++){//扫描所有头结点p=g->adjlist[i].firstarc;while(p!=NULL){A[p->adjvex]++;//表示 i 到 p->adjvex 顶点有一条边p=p->nextarc;}}printf("各个顶点的入度:\n");for(i=0;i<g->n;i++){printf(" 顶点%d:%d\n",i,A[i]);}
}
(2)求出图中每个顶点的出度。
void outdegree(AdjGraph *g){ArcNode *p;int i,n;printf("各个顶点的出度:\n");for(i=0;i<g->n;i++){n=0;p=g->adjlist[i].firstarc;while(p!=NULL){n++;p=p->nextarc;}printf(" 顶点%d:%d\n",i,n);}
}
(3)求出图中出度为0的顶点数。
void zeroOutdegree(AdjGraph *g){ArcNode *p;int i,n;printf("各出度为0的顶点:\n");for(i=0;i<g->n;i++){n=0;p=g->adjlist[i].firstarc;while(p!=NULL){n++;p=p->nextarc;}if(n==0){printf("%d\n",i);}} printf("\n");
}
三:假设一个连通图采用邻接表作为存储结构,试设计一个算法,判断其中是否存在经过顶点 v 的回路。
思想:利用深度优先遍历。从顶点 v 出发进行深度优先遍历,用 d 记录走过的路径长度,对每个访问的顶点设置标记为 1。若当前访问顶点 u,表示 vu 存在一条路径,如果顶点 u 的邻接点 w 等于 v 并且 d>1,表示顶点 u 到 v 有一条边,即构成经过顶点 v 的回路。Cycle 算法中 has 是布尔值,初始调用时置为 false,执行后若为 true 表示存在经过顶点 v 的回路, 否则表示没有相应的回路。
代码:
int visited[Max];//全局变量
void Cycle(AdjGraph *G,int u,int v,int d,int &has){//has初始为false,d=-1 int w,i;ArcNode *p;visited[u]=1;d++;p=G->adjlist.firstarc;while(p!=NULL){w=p->adjvex;if(visited[w]==0){//若顶点 w 未访问,递归访问它Cycle(G,w,v,d,has);}else if (w=v&&d>1){//u 到 v 存在一条边且回路长度大于 1has=true;return;}p=p->nextarc;//找下一个邻接点}
}
bool FindCyclePath(AdjGraph *G,int k){bool has = false;Cycle(G,v,v,-1,has);return has;
}
四:假设图 G 采用邻接表存储,试设计一个算法,判断无向图 G 是否是一棵树。若是树,返回真;否则返回假。
思想:一个无向图 G 是一棵树的条件是:G 必须是无回路的连通图或者是有 n-1 条边的 连通图。这里采用后者作为判断条件,通过深度优先遍历图 G,并求出遍历过的顶点数 vn 和边数 en,若 vn==G->n 成立(表示为连通图)且 en==2*(G->n-1)(遍历边数为 2*(G->n-1))成立,则 G 为一棵树。
代码:
//先求无向图的顶点数和边数
void DFS(AdjGraph *G,int v,int &vn,int &en){ArcNode *p;visited[v]=1;vn++;p=p->adjvex[v].firstarc;while(p!=NULL){en++;if(visited[p->adjvex]==0){DFS(G,p->adjvex,vn,en);}p=p->nextarc;}
}
//判断是否为一棵树
int IsTree(AdjGraph *G){int vn=0,en=0,i;int visited[MAX];for(i=0;i<G->n;i++){visited[i]=0;}DFS(G,1,vn,en);if(vn==G->n&&en==2*(G->n-1)){return 1;}else{return 0;}
}
思想:该实地图对应的一个无向图 G 如图所示,本题变为从指定点 k 出发找经过所有 6 条边回到 k 顶点的路径。
int vedge[MAXV][MAXV]; //边访问数组,vedge[i][j]表示(i,j)边是否访问过
void Traversal(AdjGraph *G, int u, int v, int k, int path[], int d) {//开始时,d=-1 int w,i;ArcNode *p;d++;path[d] = v; // (u,v) 加入到 path 中vedge[u][v] = vedge[v][u] = 1; // (u,v) 边已访问p = G->adjlist[v].firstarc; // p 指向顶点 v 的第一条边while (p != NULL) {w = p->adjvex; // (v,w) 有一条边if (w == k && d == G->e - 1) { // 找到一个回路,输出之printf(" %d->", k);for (i = 0; i <= d; i++) {printf("%d->", path[i]);}printf("%d\n", w);}if (vedge[v][w] == 0) { // (v,w) 未访问过,则递归访问之Traversal(G, v, w, k, path, d);}p = p->nextarc; // 找 v 的下一条边}vedge[u][v] = vedge[v][u] = 0; // 恢复环境:使该边点可重新使用
}void FindCPath(AdjGraph *G, int k) { // 输出经过顶点 k 和所有边的全部回路int path[MAXV];int i, j, v;ArcNode *p;for (i = 0; i < G->n; i++) {// vedge 数组置初值for (j = 0; j < G->n; j++)if (i == j) vedge[i][j] = 1;else vedge[i][j] = 0;}printf("经过顶点%d 的走过所有边的回路:\n", k);p = G->adjlist[k].firstarc;while (p != NULL) {v = p->adjvex;Traversal(G, k, v, k, path, -1);p = p->nextarc;}
}
六:设不带权无向图 G 采用邻接表表示,设计一个算法求源点 i 到其余各顶点的最短路径。
void ShortPath(AdjGraph *G, int i) {int qu[MAX], level[MAX]; // 队列和层次数组int front = 0, rear = 0, k, lev; // k 保存当前顶点,lev 保存从 i 到访问顶点的层数ArcNode *p; // 边节点指针visited[i] = 1; // 标记顶点 i 已访问rear++; qu[rear] = i; level[rear] = 0; // 将顶点 i 入队,初始层次为 0while (front != rear) { // 当队列不为空时执行front = (front + 1) % MAX; // 出队操作k = qu[front]; // 获取队首元素lev = level[front]; // 获取该元素的层次if (k != i) {printf("顶点%d 到顶点%d 的最短距离是:%d\n", i, k, lev); // 打印从 i 到 k 的最短距离}p = G->adjlist[k].firstarc; // 获取顶点 k 的邻接表头指针while (p != NULL) { // 遍历 k 的所有邻接点if (visited[p->adjvex] == 0) { // 如果邻接点未被访问过visited[p->adjvex] = 1; // 标记为已访问rear = (rear + 1) % MAXV; // 入队操作qu[rear] = p->adjvex; // 将邻接点入队level[rear] = lev + 1; // 更新层次}p = p->nextarc; // 移动到下一个邻接点}}
}
七: 对于一个带权有向图,设计一个算法输出从顶点 i 到顶点 j 的所有路径及其路径长度。调用该算法求出图中顶点 0 到顶点 3 的所有路径及其长度。
代码:
int visited[MAX]; //用于标记顶点是否被访问过
void findpath(AdjGraph *G, int u, int v, int path[], int d, int length) {// d 表示 path 中顶点个数,初始为 0;length 表示路径长度,初始为 0int w, i;ArcNode *p;path[d] = u; // 将顶点 u 加入到路径中d++; // 顶点数增 1visited[u] = 1; // 标记顶点 u 已访问if (u == v && d > 0) { // 如果找到一条路径且路径非空printf("路径长度:%d, 路径:", length);for (i = 0; i < d; i++) {printf("%2d", path[i]);}printf("\n");}p = G->adjlist[u].firstarc; // p 指向顶点 u 的第一个邻接点while (p != NULL) {w = p->adjvex; // w 为顶点 u 的邻接点if (visited[w] == 0) { // 如果 w 顶点未访问,递归访问它findpath(G, w, v, path, d, p->weight + length);}p = p->nextarc; // p 指向顶点 u 的下一个邻接点}visited[u] = 0; // 恢复环境,使该顶点可重新使用
}
相关文章:

李春葆《数据结构》-课后习题代码题
一:假设不带权有向图采用邻接矩阵 g 存储,设计实现以下功能的算法: (1)求出图中每个顶点的入度。 代码: void indegree(MatGraph g){int i,j,n;printf("各个顶点的入度:\n");for(i…...

51c~C语言~合集2
我自己的原文哦~ https://blog.51cto.com/whaosoft/12652943 一、嵌入式开发中的C语言编译器 如果你和一个优秀的程序员共事,你会发现他对他使用的工具非常熟悉,就像一个画家了解他的画具一样。----比尔.盖茨1 不能简单的认为是个工具 嵌入式程序开发…...

【Python】构建事件驱动架构:用Python实现实时应用的高效系统
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 事件驱动架构(Event-Driven Architecture,EDA)是一种基于事件流动进行系统设计的模式,广泛应用于游戏开发、实时监控和分布式系统中。它通过解耦事件的生产者和消费者,提升系统的可扩展性和灵活性。本文章从…...

Git(一)基本使用
目录 一、使用git -v 查看安装git版本 二、使用mkdir 创建一个文件,并使用 git init 在该目录下创建一个本地仓库, 三、通过git clone命令接入线上仓库 四、使用git status查看仓库状态信息 五、利用echo写入一个文件 并使用cat进行查看 【Linux】e…...

HarmonyOS应用开发者基础认证,Next版本发布后最新题库(10月8日更新题库未收录)
笔者会尽量找到答案的出处,力求答案准确无误。有些题目答案可能有错,也有一些笔者实在找不到出处,也不知道答案的,如果读者发现错误或有补充建议,欢迎评论或私信笔者。您的每一条反馈都是宝贵的,能够帮助笔…...

【PGCCC】Postgresql BRIN 索引原理
前言 postgresql 提供了块级索引(简称 BRIN),主要适用于类似时序数据之类的,有着天然的顺序,而且都是添加写的场景。相比于 btree 索引,它的体积小得多,非常适用于大数据量的场景。 原理 pos…...

腾讯云 AI 代码助手:产品研发过程的思考和方法论
一、文章摘要 本文将详细阐述 腾讯云 AI 代码助手的历史发展形态与产品整体架构,并从技术、研发方法论的角度分别阐述了产品的研发过程。 全文阅读约 5~8 分钟。 二、产品布局 AI 代码助手产品经历了三个时代的发展 第一代诸如 Eclipse、Jetbrains、V…...

Matlab 深度学习 PINN测试与学习
PINN 与传统神经网络的区别 与传统神经网络的不同之处在于,PINN 能够以微分方程形式纳入有关问题的先验专业知识。这些附加信息使 PINN 能够在给定的测量数据之外作出更准确的预测。此外,额外的物理知识还能在存在含噪测量数据的情况下对预测解进行正则…...

【Angular】async详解
在 Angular 中,async 关键字用于定义异步函数,通常与 await 一起使用来处理 Promise。这使得异步代码看起来更像同步代码,从而更容易理解和维护。 基本用法 定义异步函数:使用 async 关键字。等待 Promise 解析:使用…...

抖音SEO矩阵系统:开发技术分享
市场环境剖析 短视频SEO矩阵系统是一种策略,旨在通过不同平台上的多个账号建立联系,整合同一品牌下的各平台粉丝流量。该系统通过遵循每个平台的规则和内容要求,输出企业和品牌形象,以矩阵形式增强粉丝基础并提升商业价值。抖音作…...

SpringBoot集成minio,并实现文件上传
SpringBoot集成minio 什么是minioSpringBoot集成minio1、引入minio依赖2、配置Minio相关参数3、在代码里读取自定义的minio配置4、在minio配置类里,注册ConfigurationProperties实现文件上传到minio1、利用SpringMVC实现接口的异常全局处理2、返回文件路径给前端3、返回文件流…...

centos为用户赋予sudo权限
在CentOS系统中,要为用户test赋予sudo权限,你需要按照以下步骤操作: 确保sudo包已安装: 如果系统中没有安装sudo,你可以通过yum(CentOS 7及以下)或dnf(CentOS 8及以上)来…...

SAP 零售方案 CAR 系统的介绍与研究
前言 当今时代,零售业务是充满活力和活力的业务领域之一。每天,由于销售运营和客户行为,它都会生成大量数据。因此,公司迫切需要管理数据并从中检索见解。它将帮助公司朝着正确的方向发展他们的业务。 这就是为什么公司用来处理…...

Android Framework AudioFlinge 面试题及参考答案
目录 请解释什么是 AudioFlinger? AudioFlinger 在 Android 系统中的位置是什么? AudioFlinger 的主要职责有哪些? AudioFlinger 如何管理音频流? 在 AudioFlinger 中,什么是音频会话? 请简述 AudioFlinger 的工作流程。 AudioFlinger 是如何与硬件交互的? 在 A…...

嵌入式系统与单片机工作原理详解
随着现代科技的发展,嵌入式系统已经深入到我们日常生活中的方方面面。无论是智能家居、汽车电子,还是工业控制、医疗设备,都离不开嵌入式系统的支持。而单片机作为嵌入式系统的核心组件,是实现这些功能的关键之一。本文将详细介绍…...

Diving into the STM32 HAL-----Timers笔记
嵌入式设备会按时间执行某些活动。对于真正简单且不准确的延迟,繁忙的循环可以执行任务,但是使用 CPU 内核执行与时间相关的活动从来都不是一个聪明的解决方案。因此,所有微控制器都提供专用的硬件外设:定时器。定时器不仅是时基生…...

对比 MyBatis 批处理 BATCH 模式与 INSERT INTO ... SELECT ... UNION ALL 进行批量插入
前言 在开发中,我们经常需要批量插入大量数据。不同的批量插入方法有不同的优缺点,适用于不同的场景。本文将详细对比两种常见的批量插入方法: MyBatis 的批处理模式。使用 INSERT INTO ... SELECT ... UNION ALL 进行批量插入。 MyBatis …...

AI大模型如何重塑软件开发流程与模式
AI大模型如何重塑软件开发流程与模式 随着人工智能技术的不断发展,AI大模型正在逐步改变软件开发的方式。传统的软件开发流程,尽管经过多年的演进,使得许多企业能够顺利进行软件开发,但仍然面临着许多挑战,例如开发周…...

NUXT3学习日记五(composables、$fetch和useAsyncData、useFetch,lazy,refresh)
composables 在 Nuxt 3 中,composables(组合式函数)是一种用于封装和复用有状态逻辑的机制。它类似于 Vue 3 中的组合式 API,允许你将相关的逻辑(如数据获取、状态管理等)提取到独立的函数中,然…...

MySQL原理简介—10.SQL语句和执行计划
大纲 1.什么是执行计划 2.执行计划包含哪些内容 3.SQL语句和执行计划的总结 4.SQL语句使用多个二级索引 5.多表关联的SQL语句如何执行 6.全表扫描执行计划的成本计算方法 7.索引的成本计算方法 8.MySQL如何优化执行计划 9.explain的参数说明 1.什么是执行计划 (1)什么…...

wordpress二开-WordPress新增页面模板-说说微语
微语说说相当于一个简单的记事本,使用还是比较方便的。这个版本的说说微语CSS样式不兼容,可能有些主题无法适配,但是后台添加内容,前端显示的逻辑已经实现。可以当作Word press二开中自定义页面模板学习~ 一、后台添加说说微语模…...

001 MATLAB介绍
前言: 软件获取渠道有很多,难点也就是百度网盘下载慢; 线上版本每月有时间限制。 01 MATLAB介绍 性质: MATLAB即Matrix Laboratory 矩阵实验室的意思,是功能强大的计算机高级语言, 已广泛应用于各学科研究部门、…...

Linux—进程概念学习-03
目录 Linux—进程学习—31.进程优先级1.1Linux中的进程优先级1.2修改进程优先级—top 2.进程的其他概念3.进程切换4.环境变量4.0环境变量的理解4.1环境变量的基本概念4.2添加环境变量—export4.3Linux中环境变量的由来4.4常见环境变量4.5和环境变量相关的命令4.6通过系统调用获…...

低速接口项目之串口Uart开发(二)——FIFO实现串口数据的收发回环测试
本节目录 一、设计思路 二、loop环回模块 三、仿真模块 四、仿真验证 五、上板验证 六、往期文章链接本节内容 一、设计思路 串口数据的收发回环测试,最简单的硬件测试是把Tx和Rx连接在一起,然后上位机进行发送和接收测试,但是需要考虑到串…...

java: itext8.05 create pdf
只能调用windows 已安装的字体,这样可以在系统中先预装字体,5.0 可以调用自配文件夹的字体文件。CSharp donetItext8.0 可以调用。 /*** encoding: utf-8* 版权所有 2024 ©涂聚文有限公司 言語成了邀功盡責的功臣,還需要行爲每日來值班…...

如何用通义灵码快速绘制流程图?
使用通义灵码快速绘制流程图?新功能体验 不想读前人“骨灰级”代码,不想当“牛马”程序员,想像看图片一样快速读复杂代码和架构? 通义灵码已经支持代码逻辑可视化,可以把你的每段代码画成流程图。像个脑图工具一样帮你…...

vue 预览pdf 【@sunsetglow/vue-pdf-viewer】开箱即用,无需开发
sunsetglow/vue-pdf-viewer 开箱即用的pdf插件sunsetglow/vue-pdf-viewer, vue3 版本 无需多余开发,操作简单,支持大文件 pdf 滚动加载,缩放,左侧导航,下载,页码,打印,文本复制&…...

Java NIO 核心知识总结
在学习 NIO 之前,需要先了解一下计算机 I/O 模型的基础理论知识。还不了解的话,可以参考我写的这篇文章:Java IO 模型详解。 一、NIO 简介 在传统的 Java I/O 模型(BIO)中,I/O 操作是以阻塞的方式进行的。…...

疑难Tips:NextCloud域名访问登录时卡住,显示违反内容安全策略
[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ] 1使用域名访问Nextcloud用户登录时卡住,显示违反内容安全策略 我使用官方Docker镜像来部署NextCloud 28.0.5,并通过Openresty反向代理Nextcloud,但是在安装后无法稳定工作,每次登录后,页面会卡死在登录界面,无法…...

C 语言学习-06【指针】
1、目标单元与简介存取 直接访问和间接访问 #include <stdio.h>int main(void) {int a 3, *p;p &a;printf("a %d, *p %d\n", a, *p);*p 10;printf("a %d, *p %d\n", a, *p);printf("Enter a: ");scanf("%d", &a)…...