李春葆《数据结构》-课后习题代码题
一:假设不带权有向图采用邻接矩阵 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)什么…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...
python打卡day49@浙大疏锦行
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...
