图结构的创建与遍历-C语言
文章目录
- 一、 实验目的
- 二、 实验内容
- 三、 实验工具
- 四、 实验代码
- 五、 实验结果
- 六、总结与思考
一、 实验目的
理解图的基本概念,掌握图的存储结构,实现图的深度优先搜索遍历算法与广度优先搜索遍历算法。
二、 实验内容
利用邻接矩阵描述示例图,编写程序输出示例图的深度优先搜索和广度优先搜索的遍历序列。
具体步骤如下:
- 将图的邻接矩阵描述为一个二维数组,并将该数组定义为全局变量,以便数据的传递;
- 定义一个队列,在广度优先搜索时,该队列存储已被访问的路径长度为1,2,…的顶点;
- 定义访问函数visit()、深度优先搜索函数DFS()和广度优先搜索函数BFS();
- 主函数实现各函数的调用。
三、 实验工具
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;
}
五、 实验结果
六、总结与思考
- 无向图的邻接矩阵是对称的,有向图邻接矩阵可能不对称。
- 深度优先搜索类似于栈结构的出栈于入栈过程,模拟递归,其实递归也是通过堆栈的形式实现的。
- 广度遍历是非递归过程,借助队列来实现。
- 辅助数组需要在全局使用,在主函数外定义。
- DFS与BFS空间复杂度都是O(n),邻接矩阵时间复杂度都是O(n2),邻接表时间复杂度为O(n+e)。
邻接矩阵示意图:
图结构的创建与遍历-C语言相关推荐
- 二叉树的创建和遍历-C语言实现
二叉树的创建和遍历-C语言实现 链式存储结构 struct BinaryTreeNode {//数据char data;//左子树BinaryTreeNode *leftChild;//右子树Bina ...
- 图的深度优先遍历和宽度优先遍历C语言,图的广度、深度优先遍历 C语言
以下是老师作为数据结构课的作业的要求,没有什么实际用处和可以探讨和总结的的地方,所以简单代码直接展示. 宽度优先遍历: #include #include #include using namespa ...
- 二叉树的存储结构及四种遍历(C语言)
二叉树的存储结构: typedef struct TNode *Position; typedef Position BinTree; /* 二叉树类型 */ struct TNode{ /* 树结点 ...
- 【数据结构与算法】详解什么是图结构,并用代码手动实现一个图结构
本系列文章[数据结构与算法]所有完整代码已上传 github,想要完整代码的小伙伴可以直接去那获取,可以的话欢迎点个Star哦~下面放上跳转链接 https://github.com/Lpyexplo ...
- 有向完全图 java_图结构(一)
<Java常用算法手册> 引言 图(Graph)结构也是一种非线性数据结构,图结构在实际生活中有非常丰富的例子,例如:通讯网络,交通网络,人际关系网络等都可以归结为图结构.图结构的组织形式 ...
- HashMap、创建并遍历HashMap集合、LinkedHashMap
HashMap 创建并遍历HashMap集合 案例1: 键String类型,值String类型 案例2: 键Integer类型,值String类型 案例3:键String类型,值Student类型 案 ...
- C语言《数据结构》——图的概念和创建,遍历
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 例如:随着计算机网络的发展,编程成了一种很常见且重要的职业,学好编程就要学好数据结构,下面将介绍数据结构中的图结构. ...
- R语言使用forestplot包绘制森林图:编码创建森林图仿真数据、汇总线修改、元素位置调整、垂直线、字体、风格、置信区间、线型、图例、刻度、标签等
R语言使用forestplot包绘制森林图:编码创建森林图仿真数据.汇总线修改.元素位置调整.垂直线.字体.风格.置信区间.线型.图例.刻度.标签等 目录
- c语言二叉树的生成,C语言实现二叉树的创建以及遍历(递归)
C语言实现二叉树的创建以及遍历 #include typedef char ElemType; typedef struct BiTNode { ElemType data; struct BiTNo ...
最新文章
- Unknown lifecycle phase mvn
- [记录]使用openGL显示点云的一个程序
- Logistic regression--转
- linux登录密码破解
- WebKit Frame对象分析
- Java操作memcache
- unix高级编程apue.h问题
- 《线性代数及其应用》
- JS定时器使用,定时定点,固定时刻,循环执行
- 微信模版消息 errmsg: 'invalid weapp pagepath hint: [OtU1OA0868a394]
- IE浏览器常见CSS兼容性问题及解决办法
- python PIL库 Image.new 和 paste
- 动态模型之增压暂停【FunTester测试框架】
- Quartus17报错Top-level design entity “dff“ is undefined的解决办法
- Flash Remoting+ Visual Studio .NET学习总结
- 快手视频伪原创 电脑视频md5修改器
- sql填充空值_如何在SQL中使用先前的非空值填充稀疏数据
- 鸿蒙安卓字体,鸿蒙中如何自定义字体文件
- jzojs 100047. 【NOIP2017提高A组模拟7.14】基因变异
- matlab实现通信系统,香农定理的介绍
热门文章
- SPSS数据分析方法不知道如何选择​​​​​​​
- ionic3+cordova使用qr扫描仪
- linux chattr命令的使用
- android 图片滑动动画,Android实现图片滚动效果
- 恢复误删用户桌面进程导致桌面上的图标和任务栏
- PhotoShop 2022 mac相比以前的版本有哪些优势
- 推荐一款万能的图片转换器,可以批量转换支持多种格式
- PHP 字符串分割 explode 与 str_split 函数
- python有什么用?
- 无车承运人平台线路定价问题