【数据结构】图的基本操作——图的构造(邻接矩阵,邻接表),遍历(DFS,BFS)
邻接矩阵实现如下:
/*
主题:用邻接矩阵实现 DFS(递归) 与 BFS(非递归)
作者:Laugh
语言:C++
*******************************************
样例输出如下:
请选择图的类型(a - 无向图, b - 有向图):a
请输入总顶点数,总边数:8 9
请依次输入点的信息:a b c d e f g h
输入一条边依附的顶点及权值 (eg: a b 6):
a b 1
a c 1
b d 1
b e 1
d h 1
e h 1
c f 1
c g 1
f g 1
打印邻接矩阵:
0 1 1 0 0 0 0 0
1 0 0 1 1 0 0 0
1 0 0 0 0 1 1 0
0 1 0 0 0 0 0 1
0 1 0 0 0 0 0 1
0 0 1 0 0 0 1 0
0 0 1 0 0 1 0 0
0 0 0 1 1 0 0 0
请选择遍历方式(1.深度优先搜索; 2.广度优先搜索):
1
DFS:a b d h e c f g
BFS: a b c d e f g h
*/
#include <iostream>
#include <queue>
using namespace std;
#define OK 1
typedef int Status;
/* ————图的邻接矩阵存储表示 ————*/
#define MaxInt 32767 // 表示极大值
#define MVNum 100 // 最大顶点数
bool visited[MVNum]; // 访问标志数组,其初值为 “false”
typedef char VerTexType; // 假设顶点的数据类型为字符型
typedef int ArcType; // 假设边的权值类型为整型
typedef struct {
VerTexType vexs[MVNum]; // 顶点表
ArcType arcs[MVNum][MVNum]; // 邻接矩阵
int vexnum, arcnum; // 图的当前点数和边数
} AMGraph;
int LocateVex(AMGraph G, VerTexType u) {
/* 存在则返回 u 在顶点表中的下标;否则返回 -1 */
for (int i = 0; i < G.vexnum; i++)
if (u == G.vexs[i])
return i;
return -1;
}
/* ————采用邻接矩阵表示法创建无向网 ————*/
Status CreateUDN(AMGraph &G) {
int i, j, k;
char flag;
ArcType w;
VerTexType v1, v2;
cout << "请选择图的类型(a - 无向图, b - 有向图):";
cin >> flag;
cout << "请输入总顶点数,总边数:";
cin >> G.vexnum >> G.arcnum; // 输入总顶点数,总边数
cout << "请依次输入点的信息:";
for (i = 0; i < G.vexnum; i++) // 依次输入点的信息
cin >> G.vexs[i];
for (i = 0; i < G.vexnum; i++) // 初始化邻接矩阵,边的权值均置为极大值 MaxInt
for (j = 0; j < G.vexnum; j++)
G.arcs[i][j] = MaxInt;
cout << "输入一条边依附的顶点及权值 (eg: a b 6): " << endl;
for (k = 0; k < G.arcnum; k++) { // 构造邻接矩阵
cin >> v1 >> v2 >> w; // 输入一条边依附的顶点及权值
i = LocateVex(G, v1); j = LocateVex(G, v2); // 确定 v1 和 v2 在 G 中的位置,即顶点数组的下标
G.arcs[i][j] = w; // 边 <v1, v2> 的权值为 w
if (flag == 'a')
G.arcs[j][i] = G.arcs[i][j]; // 置 <v1, v2> 的对称边 <v2, v1> 的权值为 w
}
return OK;
}
/* 返回顶点v的第一个邻接顶点序号 */
int FirstAdjVex(AMGraph G, int v) {
for(int i = 0; i < G.vexnum; i++)
if(G.arcs[v][i] == 1)
return i;
return -1;
}
/* 返回顶点v的相对于w的下一个邻接顶点序号 */
int NextAdjVex(AMGraph G, int v, int w) {
for(int i = w + 1; i < G.vexnum; i++)
if(G.arcs[v][i] == 1)
return i;
return -1;
}
void DFS(AMGraph G, int v) {
visited[v]=true;
cout<<G.vexs[v]<<" ";
for(int w=FirstAdjVex(G, v); w>=0; w=NextAdjVex(G, v, w))
if(!visited[w])
DFS(G, w);
}
/* 深搜 */
void DFSTraverse(AMGraph G) {
for(int i = 0; i < G.vexnum; i++)
visited[i] = false;
for(int i = 0; i < G.vexnum; i++)
if(!visited[i])
DFS(G, i);
}
/* 广搜,类似于树的层次遍历 */
void BFSTraverse(AMGraph G) {
for(int i = 0; i < G.vexnum; i++)
visited[i] = false;
queue<int> q;
for(int i = 0; i < G.vexnum; i++) {
if(!visited[i]) {
visited[i] = true;
q.push(i);
while(!q.empty()) {
int v = q.front();
q.pop();
cout << G.vexs[v] << " ";
for(int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) {
if(!visited[w]) {
visited[w] = true;
q.push(w);
}
}
}
}
}
}
int main() {
AMGraph G;
CreateUDN(G);
cout << "打印邻接矩阵:" << endl;
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
if (G.arcs[i][j] != MaxInt)
cout << G.arcs[i][j] << " ";
else cout << '0' << " ";
}
cout << endl;
}
int flag;
cout << "请选择遍历方式(1.深度优先搜索; 2.广度优先搜索):\n";
cin >> flag;
switch(flag) {
case 1:
cout << "DFS:";
DFSTraverse(G);
cout << endl;
break;
case 2:
cout << "BFS:";
BFSTraverse(G);
cout << endl;
}
return 0;
}
邻接表实现如下:
/*
主题:用邻接表实现 DFS(递归) 与 BFS(非递归)
作者:Laugh
语言:C++
*******************************************
样例输出如下:
请输入顶点数和边数:8 9
请输入顶点:v1 v2 v3 v4 v5 v6 v7 v8
请输入边:
v1 v2
v1 v3
v2 v4
v2 v5
v4 v8
v5 v8
v3 v6
v3 v7
v6 v7
打印邻接表如下:
v1->v3->v2
v2->v5->v4->v1
v3->v7->v6->v1
v4->v8->v2
v5->v8->v2
v6->v7->v3
v7->v6->v3
v8->v5->v4
请选择遍历方式(1.深度优先搜索; 2.广度优先搜索):1
DFS:v1 v3 v7 v6 v2 v5 v8 v4
BFS: v1 v3 v2 v7 v6 v5 v4 v8
*/
#include <iostream>
#include <string>
#include <queue>
using namespace std;
bool visited[10];
/* 表结点 */
typedef struct ArcNode {
int adjvex; // 该弧所指向的顶点的位置
ArcNode *nextarc; // 指向下一条弧的指针
} ArcNode;
/* 头结点 */
typedef struct VNode {
string data; // 顶点信息
ArcNode* firstarc; // 第一个表结点的地址,指向第一条依附该顶点的弧的指针
} VNode, AdjList[10];
typedef struct {
AdjList vertices;
int vexnum, arcnum; // 图的顶点数和弧数
} ALGraph;
/* 返回顶点u在图中的位置 */
int LocateVex(ALGraph G, string u) {
for(int i = 0; i < G.vexnum; i++)
if(G.vertices[i].data == u)
return i;
return -1;
}
/* 构造无向图 */
void CreateUDG(ALGraph &G) {
string v1, v2;
int i, j, k;
cout << "请输入顶点数和边数:";
cin >> G.vexnum >> G.arcnum;
cout << "请输入顶点:";
for(i = 0; i < G.vexnum; i++) {
cin >> G.vertices[i].data;
G.vertices[i].firstarc = NULL;
}
cout << "请输入边:";
cout << endl;
for(k = 0; k < G.arcnum; k++) {
cin >> v1 >> v2;
i = LocateVex(G, v1);
j = LocateVex(G, v2);
/* 插入v1的邻接表,为了提高效率,总在表头插入结点 */
ArcNode *arc = new ArcNode;
arc->adjvex = j;
arc->nextarc = G.vertices[i].firstarc;
G.vertices[i].firstarc = arc;
/* 插入v2的邻接表,为了提高效率,总在表头插入结点 */
arc = new ArcNode;
arc->adjvex = i;
arc->nextarc = G.vertices[j].firstarc;
G.vertices[j].firstarc = arc;
}
}
/* 打印邻接表 */
void Print(ALGraph G) {
cout<<"打印邻接表如下:" << endl;
/* 遍历每个顶点的邻接表 */
for(int i = 0; i < G.vexnum; i++) {
cout << G.vertices[i].data;
ArcNode *p = G.vertices[i].firstarc;
while(p) {
cout << "->" << G.vertices[p->adjvex].data;
p = p->nextarc;
}
cout<<endl;
}
}
/* 返回顶点v的第一个邻接点序号 */
int FirstAdjVex(ALGraph G, int v) {
ArcNode *p=G.vertices[v].firstarc;
if(p)
return p->adjvex;
else
return -1;
}
/* 返回顶点v的相对于w的下一个邻接点序号 */
int NextAdjVex(ALGraph G, int v, int w) {
ArcNode* p = G.vertices[v].firstarc;
while(p) {
if(p->adjvex == w)
break;
p = p->nextarc;
}
if(p->adjvex != w || !p->nextarc)//如果没找到w或者w是最后一个邻接点
return -1;
return p->nextarc->adjvex;
}
void DFS(ALGraph G, int v) {
visited[v] = true;
cout << G.vertices[v].data << " ";
for(int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w))
if(!visited[w])
DFS(G, w);
}
void DFSTraverse(ALGraph G) {
for(int i = 0; i < G.vexnum; i++)
visited[i] = false;
for(int i = 0; i < G.vexnum; i++)
if(!visited[i])
DFS(G, i);
}
void BFSTraverse(ALGraph G) {
queue<int> q;
for(int i = 0; i < G.vexnum; i++)
visited[i] = false;
for(int i = 0; i < G.vexnum; i++) {
if(!visited[i]) {
q.push(i);
visited[i] = true;
while(!q.empty()) {
int v = q.front();
q.pop();
cout << G.vertices[v].data << " ";
for(int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w)) {
if (!visited[w]) {
q.push(w);
visited[w] = true;
}
}
}
}
}
}
int main()
{
ALGraph G;
CreateUDG(G);
Print(G);
int flag;
cout << "请选择遍历方式(1.深度优先搜索; 2.广度优先搜索):\n";
cin >> flag;
switch(flag) {
case 1:
cout << "DFS:";
DFSTraverse(G);
cout << endl;
break;
case 2:
cout << "BFS:";
BFSTraverse(G);
cout << endl;
}
return 0;
}
【数据结构】图的基本操作——图的构造(邻接矩阵,邻接表),遍历(DFS,BFS)的更多相关文章
- 数据结构学习笔记05图 (邻接矩阵 邻接表-->BFS DFS、最短路径)
数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边& ...
- PAT1013. Battle Over Cities(邻接矩阵、邻接表分别dfs)
//采用不同的图存储结构结构邻接矩阵.邻接表分别dfs,我想我是寂寞了吧,应该试试并查集,看见可以用并查集的就用dfs,bfs代替......怕了并查集了 //邻接矩阵dfs #include< ...
- 第6章 图的学习总结(邻接矩阵&邻接表)
我觉得图这一章的学习内容更有难度,其实图可以说是树结构更为普通的表现形式,它的每个元素都可以与多个元素之间相关联,所以结构比树更复杂,然而越复杂的数据结构在现实中用途就越大了,功能与用途密切联系,所以 ...
- 图的数据结构的实现与遍历(DFS,BFS)
//图的存储结构:const int MAXSIZE = 10;//邻接矩阵template<class T>class MGraph {public: MGraph(T a[], ...
- 图的全部实现(邻接矩阵 邻接表 BFS DFS 最小生成树 最短路径等)
1 /** 2 * C: Dijkstra算法获取最短路径(邻接矩阵) 3 * 6 */ 7 8 #include <stdio.h> 9 #include <stdlib.h> ...
- JAVA实现图的邻接表以及DFS
一:定义邻接表结构储存图 package 图的遍历; //邻接表实现图的建立 //储存边 class EdgeNode { int index; // 习惯了用index,其实标准写法是(adjVer ...
- <图论入门>邻接矩阵+邻接表
非本人允许请勿转载. 趁热打铁,学会了邻接表把这个总结一下,以及感谢大佬uncle-lu!!!(奶一波)祝早日进队! 首先,图论入门就得是非常基础的东西,先考虑怎么把这个图读进去. 给定一个无向图,如 ...
- 网络流三大算法【邻接矩阵+邻接表】POJ1273
网络流的基本概念跟算法原理我是在以下两篇博客里看懂的,写的非常好. http://www.cnblogs.com/ZJUT-jiangnan/p/3632525.html http://www.cnb ...
- HDU 1874 畅通工程续(最短路/spfa Dijkstra 邻接矩阵+邻接表)
题目链接: 传送门 畅通工程续 Time Limit: 1000MS Memory Limit: 65536K Description 某省自从实行了很多年的畅通工程计划后,终于修建了很多路. ...
随机推荐
- Jenkins凭证管理
目录 一.简介 二.管理凭证 三.常用凭证 保密文本 账号密码 保密文件 账号秘钥 四.优雅使用凭证 保密文本 账号密码 保密文件 五.凭证插件 集成HashiCorp Vault pipeline ...
- 查找与引用函数(Excel函数集团)
此处文章均为本妖原创,供下载.学习.探讨! 文章下载源是Office365国内版1Driver,如有链接问题请联系我. 请勿用于商业!谢谢 下载地址:https://officecommunity-m ...
- 日历共享(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 为了某一个项目,我们建好了一整套的日历,除了标准日历里加上了所有的假期以外,其他来自火星的水星的金星的土星的木星的BT的不 ...
- JavaFx WebView使用研究
原文: JavaFx WebView使用研究 | Stars-One的杂货小窝 本篇是基于TornadoFx框架的基础研究的,示例代码都是Kotlin版本,各位可以看着参考下 WebView中比较重要 ...
- jenkins+docker+k8s项目发布
目录 一.简介 二.新建docker-build工程 三.项目部署 四.访问测试 一.简介 1.该章节基于jenkins.Harbor.pipeline.k8s来做发布,如对这些不熟悉,请按以下进入学 ...
- MySQL查询列必须和group by字段一致吗?
@ 目录 场景:查询各部门薪水最高的员工. 方法一: 方法二: MySQL group by是如何决定哪一条数据留下的? 分组前的数据: 那么target list和group by column不匹 ...
- .net Core 使用 iTextSharp 生成PDF 简单示例
在 Nuget 中导入需要的插件: 实现的代码: 1 [HttpGet, Route("CreatePdf")] 2 public Response CreatePdf() 3 { ...
- 往docker中的mysql导入sql文件
先把sql文件上传到服务器 然后拷贝sql文件到docker中的mysql 容器中 docker cp test.sql mysql:/test.sql 这里的mysql都是容器名称 根据自己的来 用 ...
- JAVA实现智能分词(通过文章标题生成tag标签)
导入jar包 IKAnalyzer2012_u6.jar下载链接:https://pan.xunlew.com/s86789 maven <dependency> <groupId& ...
- ffmpeg、数字音频教程、JUCE、std::tuple
下载网易云音乐的视频 https://yunyinyue.iiilab.com/ 模板教程: https://github.com/wuye9036/CppTemplateTutorial/blob/ ...