【数据结构——图】图的遍历(头歌习题)【合集】

目录

  • 第1关:邻接矩阵存储图的深度优先遍历
    • 任务描述
    • 相关知识
      • 邻接矩阵存储图
      • 图的遍历
        • DFS伪代码——邻接矩阵存储实现
    • 完整代码
  • 第2关:邻接表存储图的广度优先遍历
    • 任务描述
    • 相关知识
      • 邻接表存储图
      • 图的遍历
        • 广度优先遍历过程:
        • BFS伪代码——邻接表实现
    • 编程要求
    • 测试说明
    • 完整代码

第1关:邻接矩阵存储图的深度优先遍历

任务描述

本关任务:请你实现 dfs.cpp 里的void DFS( MatGraph* G, VertexType V)函数。 约定:顶点编号小的先输出。

相关知识

为了完成本关任务,你需要掌握:1.如何使用邻接矩阵存储图,2.如何遍历图。

邻接矩阵存储图

一个包含6个顶点的无向图如图所示。
请添加图片描述
图1 一个包含6个顶点的无向图

图 2 给出了对图 1 的无向图的存储结构图:每个顶点的名称由一个整数描述,顶点的相邻关系保存在邻接矩阵中,矩阵中值为 1 表示i号顶点到j号顶点有边,为 0 表示无边。
请添加图片描述
图2 图1的无向图的邻接矩阵

图的邻接矩阵定义如下:

typedef struct             //图的定义
{   int edges[MAXV][MAXV]; //邻接矩阵int n, e;              //顶点数, 边数VertexType vexs[MAXV]; //存放顶点信息
}  MatGraph;

给定指向该结构的指针G,就可以对图进行操作。

图的遍历

所谓图的遍历(graph traversal),也称为搜索(search),就是从图中某个顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次。遍历可以采取两种方法进行:深度优先搜索(DFS,depth first search)和广度优先搜索(BFS,breadth first search)。

深度优先遍历过程:
(1)从图中某个初始顶点v出发, 首先访问初始顶点v。
(2)选择一个与顶点v相邻且没被访问过的顶点w, 再从w出发进行深度优先搜索, 直到图中与当前顶点v邻接的所有顶点都被访问过为止。

算法设计思路:
深度优先遍历的过程体现出后进先出的特点:用栈或递归方式实现。
请添加图片描述

如何确定一个顶点是否访问过? 设置一个visited[] 全局数组, visited[i]=0表示顶点i没有访问; visited[i]=1表示顶点i已经访问过。

DFS伪代码——邻接矩阵存储实现

如果用邻接矩阵存储图(设顶点个数为 n),则 DFS 算法实现的伪代码如下:

DFS(图G, 顶点 i ) //从顶点 i 进行深度优先搜索
{ visited[ i ] = 1; //将顶点 i 的访问标志置为 1 for( j=0; j<n; j++ ) //对其他所有顶点 j { //j 是 i 的邻接顶点,且顶点 j 没有访问过if( edges[i][j]==1 && !visited[j] ) { //递归搜索前的准备工作需要在这里写代码 DFS( j ); //从顶点 j 出发进行 DFS 搜索//以下是 DFS 的回退位置,在很多应用中需要在这里写代码  } } 
}

对图1运行该算法的结果(从顶点5出发): 5 0 1 3 2 4。

编程要求
请你在右侧的代码窗口中实现dfs.cpp里的void DFS( MatGraph* G, VertexType V)函数。 注意遵守约定:顶点编号小的先输出。

测试说明
本关的测试过程如下:
1.平台编译 step1/dfs.cpp ;
2.平台运行该可执行文件,并以标准输入方式提供测试输入;
3.平台获取该可执行文件的输出,然后将其与预期输出对比,如果一致则测试通过;否则测试失败。
输入输出格式说明:

输入格式:
输入V,开始遍历的起始顶点编号。

输出格式:
输出对图进行深度优先遍历的顶点序列,每个顶点编号前面有一个空格。

以下是平台对 step1/dfs.cpp 的测试样例:

样例输入:
无向图
请添加图片描述
测试输入:5

样例输出:
预期输出:DFS from 5: 5 1 3 0 2 4 6

开始你的任务吧,祝你成功!

完整代码

 #include "dfs.h"/** 从顶点V出发进行深度优先搜索。* 函数DFS应从编号为V的顶点出发递归地深度优先遍历图,* 遍历访问邻接点时,要求按序号递增的顺序。* 题目保证V是图中的合法顶点。* 参数G为邻接矩阵存储的图的表示。*/
void DFS( MatGraph* G, VertexType V)
{/*** 请在下面的begin..end间编写程序代码,* 勿修改begin..end之外的代码。*//*******************begin*******************/int i=V; // 开始顶点visited[i]=1;printf(" %d", i);int j;for(j=0; j<G->n; j++){if(G->edges[i][j]==1 && !visited[j]){DFS(G, j);}}/*******************end********************/
}int main()
{MatGraph* G;VertexType V;G = CreateGraph();scanf("%d", &V);printf("DFS from %d:", V);DFS(G, V);return 0;
}

在这里插入图片描述

第2关:邻接表存储图的广度优先遍历

任务描述

本关任务:请你实现 bfs.cpp 里的void BFS( AdjGraph* G, VertexType V)函数。 约定:顶点编号小的先输出。

相关知识

为了完成本关任务,你需要掌握:1.如何使用邻接表存储图,2.如何遍历图。

邻接表存储图

一个包含5个顶点的无向图如图所示。
一个包含5个顶点的无向图

图1 一个包含5个顶点的无向图
请添加图片描述

图 2 给出了对图 1 的无向图的邻接表存储结构图:每个顶点的名称由一个整数描述,对图中每个顶点i建立一个单链表, 将顶点i的所有邻接点链起来。

每个顶点的邻接表
请添加图片描述
每个单链表上添加一个表头结点(表示顶点信息)。并将所有表头结点构成一个数组, 下标为i的元素表示顶点i的表头结点。

邻接表
请添加图片描述

图2 图1的无向图的邻接表

图的邻接表存储方法是一种顺序分配与链式分配相结合的存储方法,如图3所示。

图的邻接表
请添加图片描述

图3 图的邻接表表示形式

一个带权的有向图(网)的邻接表存储形式如图4所示。

带权有向图的邻接表存储形式
请添加图片描述
图4 带权有向图的邻接表存储结构图

图的邻接表存储类型定义如下:

typedef struct ANode
{     int adjvex;            //该边的终点编号struct ANode *nextarc;    //指向下一条边的指针int weight;            //该边的权值等信息
}  ArcNode;
typedef struct Vnode
{    Vertex data;            //顶点信息ArcNode *firstarc;        //指向第一条边
}  VNode;
typedef struct 
{     VNode adjlist[MAXV] ;    //邻接表int n, e;        //图中顶点数n和边数e
} AdjGraph;

个邻接表通常用指针引用:

带权有向图的邻接表 请添加图片描述
给定指向该结构的指针G,就可以对图进行操作。

图的遍历

所谓图的遍历(graph traversal),也称为搜索(search),就是从图中某个顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次。遍历可以采取两种方法进行:深度优先搜索(DFS,depth first search)和广度优先搜索(BFS,breadth first search)。

广度优先遍历过程:

广度优先搜索(BFS,Breadth First Search)是一个分层的搜索过程,没有回退过程,是非递归的。其访问过程如下:
(1)访问初始点v, 接着访问v的所有未被访问过的邻接点v1, v2, …, vt。
(2)按照v1, v2, …, vt的次序, 访问每一个顶点的所有未被访问过的邻接点。   
(3)依次类推, 直到图中所有和初始点v有路径相通的顶点都被访问过为止。

算法设计思路:
广度优先搜索遍历体现先进先出的特点, 用队列实现。

广度优先搜索过程 请添加图片描述

如何确定一个顶点是否访问过? 设置一个visited[] 全局数组, visited[i]=0表示顶点i没有访问; visited[i]=1表示顶点i已经访问过。

BFS伪代码——邻接表实现

如果用邻接表存储图,则 BFS 算法实现的伪代码如下:

BFS(图 G, 顶点 i ) //从顶点 i 进行广度优先搜索
{ visited[ i ] = 1; //将顶点 i 的访问标志置为 1 
将顶点 i 入队列; while( 队列不为空 ) { 取出队列头的顶点,设为 k p = 顶点 k 的边链表表头指针while( p 不为空 ) { //设指针 p 所指向的边结点所表示的边的另一个顶点为顶点 j if( 顶点 j 未访问过 ) { 将顶点 j 的访问标志置为 1 将顶点 j 入队列} p = p->nextarc; //p 移向下一个边结点} //end of while } //end of while 
} //end of BFS

对图1运行该算法的结果(从顶点2出发): 2 1 3 4 0。

编程要求

请你在右侧的代码窗口中实现bfs.cpp里的void BFS( AdjGraph* G, VertexType V)函数。 注意遵守约定:顶点编号小的先输出。

注:本关提供C++ STL队列容器queue,你可以直接使用。

测试说明

本关的测试过程如下:
1.平台编译 step2/bfs.cpp 并生成可执行文件;
2.平台运行该可执行文件,并以标准输入方式提供测试输入;
3.平台获取该可执行文件的输出,然后将其与预期输出对比,如果一致则测试通过;否则测试失败。
输入输出格式说明:

输入格式:
输入V,开始遍历的起始顶点编号。

输出格式:
输出对图进行广度优先遍历的顶点序列,每个顶点编号前面有一个空格。

以下是平台对 step2/bfs.cpp 的测试样例:

样例输入:
无向图
请添加图片描述

测试输入:2

样例输出:
预期输出:BFS from 2: 2 0 3 5 4 1 6

开始你的任务吧,祝你成功!

完整代码

#include "bfs.h"/** 从顶点V出发进行广度优先搜索。* 函数BFS应从编号为V的顶点出发广度优先遍历图,* 遍历访问邻接点时,要求按序号递增的顺序。* 题目保证V是图中的合法顶点。*/
void BFS( AdjGraph* G, VertexType V)
{/*******************begin*******************/int k; // 队列头顶点int i=V;ArcNode *p;  // 链表// 初始化队列  队列保存访问过的顶点queue<int> qu;// 初始化visited数组int visited[MAXV];for(int b=0; b<G->n; b++){visited[b]=0;}printf(" %d", i);visited[i]=1;// 开始BFSqu.push(i);while(!qu.empty()){k = qu.front();qu.pop(); p = G->adjlist[k].firstarc;while(p!=NULL){if(visited[p->adjvex]==0){  // 当前节点未访问printf(" %d", p->adjvex);visited[p->adjvex]=1;qu.push(p->adjvex);}p=p->nextarc;}}/*******************end*******************/
}int main()
{AdjGraph* G;VertexType V;G = CreateGraph();scanf("%d", &V);printf("BFS from %d:", V);BFS(G, V);return 0;
}

在这里插入图片描述

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

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

相关文章

分布式IO在工业自动化中的应用

传统的自动化产线及物流系统主要是利用PLC来处理数据&#xff0c;并将这些数据保存在PC当中。但是随着互联网技术的迅速发展&#xff0c;越来越多的系统集成商利用分布式IO模块&#xff0c;实现从控制器到自动化最底层之间的IO通信。 分布式IO在工业自动化中的应用 分布式IO是用…

基于简化版python+VGG+MiniGoogLeNet的智能43类交通标志识别—深度学习算法应用(含全部python工程源码)+数据集+模型(二)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理2. 模型构建1&#xff09;VGG模型简化版2&#xff09;GoogLeNet简化版——MiniGoogLeNet 3. 模型训练及保存 相关其它博客工程源代码下载其它资料下载 前言 本项目专注于解决出国自驾游特定场景下的交…

(1)(1.13) SiK无线电高级配置(一)

文章目录 前言 1 监控链接质量 2 诊断范围问题 前言 本文提供 SiK 遥测无线电(SiK Telemetry Radio)的高级配置信息。它面向"高级用户"和希望更好地了解无线电如何运行的用户。 &#xff01;Tip 大多数用户只需要 SiK Radio v2 中提供的基本指南和功能概述。 1 …

【重磅新品】小眼睛科技推出紫光同创盘古系列FPGA开发板套件,盘古200K开发板,紫光同创PG2L200H,Logos2系列

FPGA&#xff0c;即现场可编程门阵列&#xff0c;作为可重构电路芯片&#xff0c;已经成为行业“万能芯片”&#xff0c;在通信系统、数字信息处理、视频图像处理、高速接口设计等方面都有不俗的表现。近几年&#xff0c;随着国家战略支持和产业发展&#xff0c;国产FPGA迎来迅…

常用设计模式全面总结版(JavaKotlin)

这篇文章主要是针对之前博客的下列文章的总结版本: 《设计模式系列学习笔记》《Kotlin核心编程》笔记:设计模式【Android知识笔记】FrameWork中的设计模式主要为了在学习了 Kotlin 之后,将 Java 的设计模式实现与 Kotin 的实现放在一起做一个对比。 一、创建型模式 单例模…

如何解决企业内部FTP文件传输速度过慢和安全问题

在数据化时代里&#xff0c;企业内部的文件传输永远是刚需&#xff0c;而因为 FTP协议的简单、易用、广泛支持等优点&#xff0c;让很多企业早期都普遍使用&#xff0c;随着数量量的增多&#xff0c;和对安全的要求越来越高&#xff0c;FTP也暴露出了一些列问题&#xff0c;小编…

C++构建简单静态库实例(cmakelist)

一、开发实例 通过cmake构建静态开发实例如下: 1.1 代码目录 代码目录结构如下: 1.2 代码内容 1.2.1 CMakeLists.txt # CMake 最低版本要求 cmake_minimum_required(VERSION 3.10)# 项目名称 project(mylib)# 添加源文件 set(SOURCE_FILESsrc/mylib

谷歌Linux内核自动测试平台架构介绍-用自动测试测试难以测试的问题

1 摘要 内核和硬件等低级系统已被证明极难进行有效测试&#xff0c;因此&#xff0c;许多内核测试都是以手动为主方式进行的。现有的大多数测试框架都是为测试与底层平台隔离的高级软件而设计的&#xff0c;而底层平台被假定是稳定可靠的。测试底层平台本身需要一套全新的假设…

互联网大厂面试题目

阿里篇 1.1.1 如何实现一个高效的单向链表逆序输出&#xff1f; 1.1.2 已知sqrt(2)约等于1.414&#xff0c;要求不用数学库&#xff0c;求sqrt(2)精确到小数点后10位 1.1.3 给定一个二叉搜索树(BST)&#xff0c;找到树中第 K 小的节点 1.1.4 LRU缓存机制 1.1.5 关于epoll和…

table表格中使用el-popover 无效问题解决

实例只针对单个的按钮管用在表格里每一列都有el-popover相当于是v-for遍历了 所以我们在触发按钮的时候并不是单个的触发某一个 主要执行 代码 <el-popover placement"left" :ref"popover-${scope.$index}"> 动态绑定了ref 关闭弹窗 执行deltask…

mysql的索引原理

目录 一、索引采用B树的优势二、为什么不使用其他数据结构2.1、哈希索引2.2平衡二叉树B树 参考 mysql索引采用B树 一、索引采用B树的优势 1可以进行范围查找&#xff0c;通过单向链表解决&#xff08;通过单向链表已经排好序&#xff09;。 2非叶子结点只存储key&#xff0c;不…

【Java EE初阶三 】线程的状态与安全(下)

3. 线程安全 线程安全&#xff1a;某个代码&#xff0c;不管它是单个线程执行&#xff0c;还是多个线程执行&#xff0c;都不会产生bug&#xff0c;这个情况就成为“线程安全”。 线程不安全&#xff1a;某个代码&#xff0c;它单个线程执行&#xff0c;不会产生bug&#xff0c…

Git:常用命令(二)

查看提交历史 1 git log 撤消操作 任何时候&#xff0c;你都有可能需要撤消刚才所做的某些操作。接下来&#xff0c;我们会介绍一些基本的撤消操作相关的命令。请注意&#xff0c;有些操作并不总是可以撤消的&#xff0c;所以请务必谨慎小心&#xff0c;一旦失误&#xff0c…

地下城游戏(dp问题)

1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 从下往上填&#xff0c;每一行&#xff0c;每一行从右往左 5.返回值 dp[0][0]

OpenCV-Python(21):OPenCV查找及绘制轮廓

1.认识轮廓 1.1 目标 理解什么是轮廓学习掌握找轮廓、绘制轮廓等学习使用cv2.findContours()、cv2.drawContours()函数的用法 1.2 什么是轮廓 在OpenCV中&#xff0c;轮廓是图像中连续的边界线的曲线&#xff0c;具有相同的颜色或者灰度&#xff0c;用于表示物体的形状。轮廓…

docker 在线安装mysql 8.0.21版本

1、拉取mysql 8.0.21版本镜像 2、查看镜像 docker images 3、在宿主机 /usr/local/mysql 下的 conf 文件夹下&#xff0c;创建 my.cnf 文件&#xff0c;并编辑内容 [mysql] default-character-setutf8 [client] port3306 default-character-setutf8 [mysqld] port3306 se…

前后台分离开发

前后台分离开发 简介 前后台分离开发&#xff0c;就是在项目开发过程中&#xff0c;对于前端代码的开发由专门的前端开发人员负责&#xff0c;后端代码则由后端开发人员负责&#xff0c;这样可以做到分工明确、各司其职&#xff0c;提高开发效率&#xff0c;前后端代码并行开…

20231231_小米音箱接入GPT

参考资料&#xff1a; GitHub - yihong0618/xiaogpt: Play ChatGPT and other LLM with Xiaomi AI Speaker *.设置运行脚本权限 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned *.配置小米音箱 ()pip install miservice_fork -i https://pypi.tuna.tsinghua.edu.cn/sim…

单机+内部备份_全备案例

此场景为单机数据库节点内部备份&#xff0c;方便部署和操作&#xff0c;但备份REPO与数据库实例处于同一个物理主机&#xff0c;冗余度较低。 前期准备 配置ksql免密登录(必须) 在Kingbase数据库运行维护中&#xff0c;经常用到ksql工具登录数据库&#xff0c;本地免密登录…

Kafka安装及简单使用介绍

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…