文章目录

  • 一、 实验目的
  • 二、 实验内容
  • 三、 实验工具
  • 四、 实验代码
  • 五、 实验结果
  • 六、总结与思考

一、 实验目的

理解图的基本概念,掌握图的存储结构,实现图的深度优先搜索遍历算法与广度优先搜索遍历算法。

二、 实验内容

利用邻接矩阵描述示例图,编写程序输出示例图的深度优先搜索和广度优先搜索的遍历序列。


具体步骤如下:

  1. 将图的邻接矩阵描述为一个二维数组,并将该数组定义为全局变量,以便数据的传递;
  2. 定义一个队列,在广度优先搜索时,该队列存储已被访问的路径长度为1,2,…的顶点;
  3. 定义访问函数visit()、深度优先搜索函数DFS()和广度优先搜索函数BFS();
  4. 主函数实现各函数的调用。

三、 实验工具

Dev-C++

四、 实验代码

//Authors:xiaobei#include<stdio.h>
#include<stdlib.h>
#define MaxInt 32767
#define MVNum 100
typedef char VerTexType;
typedef int ArcType;
//定义图结构
typedef struct{VerTexType vexs[MVNum];ArcType arcs[MVNum][MVNum];int vexnum,arcnum;
}AMGraph;
//定义辅助链队
typedef struct QNode{char data;struct QNode *next;
}QNode,*QueuePtr;
typedef struct{QueuePtr front;QueuePtr rear;
}LinkQueue;
//定义全局辅助数组visited[MVNum]
int visited[MVNum];
//函数返回定点下标
int LocateVex(AMGraph G,char v){int i;for(i=0;i<G.vexnum;i++)if(G.vexs[i]==v)return i;return -1;
}
//函数访问并输出顶点,返回下标
int visit(AMGraph G,char v){int i;for(i=0;i<G.vexnum;i++)if(v==G.vexs[i])printf("%c",v);return LocateVex(G,v);
}
//函数创建无向图,以邻接矩阵形式
int CreateUDN(AMGraph &G){int i,j,k,v1,v2,w;printf("[输入总顶点数和边数:]\n>>>");scanf("%d %d",&G.vexnum,&G.arcnum);for(i=0;i<G.vexnum;i++){getchar();printf("[依次输入各顶点的信息:]\n>>>");scanf("%c",&G.vexs[i]);}for(i=0;i<G.vexnum;i++)for(j=0;j<G.vexnum;j++)G.arcs[i][j] = MaxInt;for(k=0;k<G.arcnum;k++){getchar();printf("[输入一条边依附的顶点及权值:]\n>>>"); scanf("%c %c %d",&v1,&v2,&w);i = LocateVex(G,v1);j = LocateVex(G,v2);G.arcs[i][j]=w;G.arcs[j][i]=G.arcs[i][j];}return 1;
}
//函数深度遍历连通图
void DFS_AM(AMGraph G,char v){int w,u;u = visit(G,v);visited[u] = 1;for(w=0;w<G.vexnum;w++){if((G.arcs[u][w]<MaxInt) && (!visited[w]))DFS_AM(G,G.vexs[w]);}
}
//函数初始化链队
void InitQueue(LinkQueue &Q){Q.front = Q.rear = (QNode*)malloc(sizeof(QNode));Q.front->next=NULL;
}
//函数数据进队
void EnQueue(LinkQueue &Q,char e){QueuePtr p;p = (QNode*)malloc(sizeof(QNode));p->data = e;p->next = NULL;Q.rear->next=p;Q.rear = p;
}
//函数数据出队
void DeQueue(LinkQueue &Q,char &e){QueuePtr p;if(Q.front==Q.rear);else{p = Q.front->next;e = p->data;Q.front->next = p->next;if(Q.rear==p)Q.rear=Q.front;free(p);}
}
//函数判断链队是否为空
int QueueEmpty(LinkQueue Q){if(Q.front==Q.rear)return 1;elsereturn 0;
}
//函数返回顶点下一个邻接点下标
int FirstAdjVex(AMGraph G,int c){int j;for(j=0;j<G.vexnum;j++)if(G.arcs[c][j]<MaxInt && visited[j]==0)return j;return -1;
}
//函数返回顶点下一个相对邻接点下标
int NextAdjVex(AMGraph G,int c,int w){int j;for(j=0;j<G.vexnum;j++)if(G.arcs[c][j]<MaxInt && visited[j]==0)return j;return -1;
}
//函数广度遍历连通图
void BFS_AM(AMGraph G,char v){int c,w,i;char u;LinkQueue Q;c = visit(G,v);visited[c] = 1;InitQueue(Q);EnQueue(Q,v);while(!QueueEmpty(Q)){DeQueue(Q,u);c = LocateVex(G,u);for(w=FirstAdjVex(G,c);w>=0;w=NextAdjVex(G,c,w)){if(!visited[w]){i = visit(G,G.vexs[w]);visited[i] = 1;EnQueue(Q,G.vexs[w]);}}}
}
//菜单打印
void Menu(){printf("\n————————菜单————————\n");printf("\n1.创建图结构;\n");printf("\n2.深度遍历(DFS);\n");printf("\n3.广度遍历(BFS);\n");printf("\n0.退出;\n");printf("\n——————————————————\n");printf("[请输入你的选择:]\n>>>");
}
//主函数
int main(){int i,user;char v;AMGraph G;while(1){Menu();scanf("%d",&user);switch(user){case 1:{CreateUDN(G);break;}case 2:{//初始化辅助数组for(i=0;i<G.vexnum;i++)visited[i] = 0;printf("[请输入遍历开始的顶点:]\n>>>");getchar();scanf("%c",&v);DFS_AM(G,v);break;}case 3:{//初始化辅助数组for(i=0;i<G.vexnum;i++)visited[i] = 0;printf("[请输入遍历开始的顶点:]\n>>>");getchar();scanf("%c",&v);BFS_AM(G,v);break;}case 0:{exit(0);break;}}}return 0;
}

五、 实验结果




六、总结与思考

  1. 无向图的邻接矩阵是对称的,有向图邻接矩阵可能不对称
  2. 深度优先搜索类似于栈结构的出栈于入栈过程,模拟递归,其实递归也是通过堆栈的形式实现的。
  3. 广度遍历是非递归过程,借助队列来实现。
  4. 辅助数组需要在全局使用,在主函数外定义
  5. DFS与BFS空间复杂度都是O(n),邻接矩阵时间复杂度都是O(n2),邻接表时间复杂度为O(n+e)。

邻接矩阵示意图:

图结构的创建与遍历-C语言相关推荐

  1. 二叉树的创建和遍历-C语言实现

    二叉树的创建和遍历-C语言实现 链式存储结构 struct BinaryTreeNode {//数据char data;//左子树BinaryTreeNode *leftChild;//右子树Bina ...

  2. 图的深度优先遍历和宽度优先遍历C语言,图的广度、深度优先遍历 C语言

    以下是老师作为数据结构课的作业的要求,没有什么实际用处和可以探讨和总结的的地方,所以简单代码直接展示. 宽度优先遍历: #include #include #include using namespa ...

  3. 二叉树的存储结构及四种遍历(C语言)

    二叉树的存储结构: typedef struct TNode *Position; typedef Position BinTree; /* 二叉树类型 */ struct TNode{ /* 树结点 ...

  4. 【数据结构与算法】详解什么是图结构,并用代码手动实现一个图结构

    本系列文章[数据结构与算法]所有完整代码已上传 github,想要完整代码的小伙伴可以直接去那获取,可以的话欢迎点个Star哦~下面放上跳转链接 https://github.com/Lpyexplo ...

  5. 有向完全图 java_图结构(一)

    <Java常用算法手册> 引言 图(Graph)结构也是一种非线性数据结构,图结构在实际生活中有非常丰富的例子,例如:通讯网络,交通网络,人际关系网络等都可以归结为图结构.图结构的组织形式 ...

  6. HashMap、创建并遍历HashMap集合、LinkedHashMap

    HashMap 创建并遍历HashMap集合 案例1: 键String类型,值String类型 案例2: 键Integer类型,值String类型 案例3:键String类型,值Student类型 案 ...

  7. C语言《数据结构》——图的概念和创建,遍历

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 例如:随着计算机网络的发展,编程成了一种很常见且重要的职业,学好编程就要学好数据结构,下面将介绍数据结构中的图结构. ...

  8. R语言使用forestplot包绘制森林图:编码创建森林图仿真数据、汇总线修改、元素位置调整、垂直线、字体、风格、置信区间、线型、图例、刻度、标签等

    R语言使用forestplot包绘制森林图:编码创建森林图仿真数据.汇总线修改.元素位置调整.垂直线.字体.风格.置信区间.线型.图例.刻度.标签等 目录

  9. c语言二叉树的生成,C语言实现二叉树的创建以及遍历(递归)

    C语言实现二叉树的创建以及遍历 #include typedef char ElemType; typedef struct BiTNode { ElemType data; struct BiTNo ...

最新文章

  1. Unknown lifecycle phase mvn
  2. [记录]使用openGL显示点云的一个程序
  3. Logistic regression--转
  4. linux登录密码破解
  5. WebKit Frame对象分析
  6. Java操作memcache
  7. unix高级编程apue.h问题
  8. 《线性代数及其应用》
  9. JS定时器使用,定时定点,固定时刻,循环执行
  10. 微信模版消息 errmsg: 'invalid weapp pagepath hint: [OtU1OA0868a394]
  11. IE浏览器常见CSS兼容性问题及解决办法
  12. python PIL库 Image.new 和 paste
  13. 动态模型之增压暂停【FunTester测试框架】
  14. Quartus17报错Top-level design entity “dff“ is undefined的解决办法
  15. Flash Remoting+ Visual Studio .NET学习总结
  16. 快手视频伪原创 电脑视频md5修改器
  17. sql填充空值_如何在SQL中使用先前的非空值填充稀疏数据
  18. 鸿蒙安卓字体,鸿蒙中如何自定义字体文件
  19. jzojs 100047. 【NOIP2017提高A组模拟7.14】基因变异
  20. matlab实现通信系统,香农定理的介绍

热门文章

  1. SPSS数据分析方法不知道如何选择​​​​​​​
  2. ionic3+cordova使用qr扫描仪
  3. linux chattr命令的使用
  4. android 图片滑动动画,Android实现图片滚动效果
  5. 恢复误删用户桌面进程导致桌面上的图标和任务栏
  6. PhotoShop 2022 mac相比以前的版本有哪些优势
  7. 推荐一款万能的图片转换器,可以批量转换支持多种格式
  8. PHP 字符串分割 explode 与 str_split 函数
  9. python有什么用?
  10. 无车承运人平台线路定价问题