#include <iostream>
#include <queue>
using namespace std;
//图的邻接矩阵存储表示
#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;
//确定顶点位置
int LocateVex(AMGraph G, VerTexType v)
{
int i;
for (i = 0; i < G.vexnum; ++i)
{
if (G.vexs[i] == v)
{
break;
}
}
return i;
}
//用邻接矩阵创建无向图
bool CreateUDN(AMGraph& G)
{
int i, j, k;
cout << "请输入总顶点数:" << endl;
cin >> G.vexnum;
cout << "请输入总边数:" << endl;
cin >> G.arcnum;
//依次输入点的信息,存入顶点表中
cout << "请依次输入点的消息:" << endl;
for (int i = 0; i < G.vexnum; ++i)
{
cin >> G.vexs[i];
}
//初始化邻接矩阵,边的权值均置为极大值MaxInt
for (int i = 0; i < G.vexnum; ++i)
{
for (int j = 0; j < G.vexnum; ++j)
{
G.arcs[i][j] = MaxInt;
}
}
//构造邻接矩阵
for (int k = 0; k < G.arcnum; ++k)
{
//1.定义两个顶点和边的权值
VerTexType v1 = 0, v2 = 0;
ArcType w = 0;
cout << "请分别输入边上的两点及边的权值:" << endl;
cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值
//2.确定两个顶点在图中的位置
i = LocateVex(G, v1);
j = LocateVex(G, v2);
//3.两个顶点之间的权值
G.arcs[i][j] = w; //边<v1,v2>的权值置为w
//4.无向图邻接矩阵权值对称
G.arcs[j][i] = G.arcs[i][j]; //置<v1,v2>的对称边<v2,v1>的权值为w
}
return 1;
}
//返回第一个邻接点
VerTexType getFirstNeighbor(VerTexType v, AMGraph G)
{
int i = LocateVex(G, v); //找到顶点v的存储位置
for (int j = i; j < G.vexnum; j++)
{
if (G.arcs[i][j] > 0)
{
return G.vexs[j]; //找到第一个大于0的边
}
}
return '0'; //不存在则返回'0'
}
//返回下一个邻接点
VerTexType getNextNeighbor(VerTexType v, VerTexType w, AMGraph G)
{
int i = LocateVex(G, v);
int j = LocateVex(G, w);
for (int k = j + 1; k < G.vexnum; k++)
{
//从w开始找,找到w后面第一个大于0的边
if (G.arcs[i][k] > 0 && G.arcs[i][k] != 32767)
{
return G.vexs[k];
}
}
return '0'; //不存在则返回'0'
}
//深度优先遍历
int visited[MVNum]; //访问标记数组
void DFS(AMGraph G, VerTexType v)
{
cout << v << " ";
visited[LocateVex(G, v)] = 1;
for (VerTexType w = getFirstNeighbor(v, G); w != '0'; w = getNextNeighbor(v, w, G))
{
if (!visited[LocateVex(G, w)])
{
DFS(G, w);
}
}
}
void DFSTraverse(AMGraph G)
{
int count = 0; //连通分量的初始值为0
for (int i = 0; i < G.vexnum; i++)
{
visited[i] = 0; //初始化标记数组
}
for (int i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
DFS(G, G.vexs[i]);
count++; //每调用一次DFS,连通分量就增加一个
}
}
cout << endl;
cout << "连通分量的数量为:" << count << endl;
}
//广度优先遍历
void BFS(AMGraph G, VerTexType v)
{
queue<VerTexType> vex; //借助队列存储邻接顶点
cout << v << " ";
visited[LocateVex(G, v)] = 1;
vex.push(v);
while (!vex.empty())
{
VerTexType u = vex.front(); //获取队首元素
vex.pop(); //出队
for (VerTexType w = getFirstNeighbor(u, G); w != '0'; w = getNextNeighbor(u, w, G))
{
if (!visited[LocateVex(G, w)])
{
cout << w << " ";
visited[LocateVex(G, w)] = 1;
vex.push(w); //入队
}
}
}
}
void BFSTraverse(AMGraph G)
{
int count = 0; //连通分量的初始值为0
for (int i = 0; i < G.vexnum; i++)
{
visited[i] = 0; //初始化标记数组
}
for (int i = 0; i < G.vexnum; i++)
{
if (!visited[i])
{
BFS(G, G.vexs[i]);
count++; //每调用一次BFS,连通分量就增加一个
}
}
cout << endl;
cout << "连通分量的数量为:" << count << endl;
}
int main()
{
AMGraph G;
int k;
cout << "1:创建无向图 2:打印邻接矩阵 3:深度遍历 4:广度遍历 5:退出程序" << endl;
cout << endl;
do
{
cout << "请输入相应数值,选择操作:" << endl;
cin >> k;
switch (k)
{
case 1:
CreateUDN(G);
cout << endl;
break;
case 2:
cout << "邻接矩阵为:" << endl;
for (int i = 0; i < G.vexnum; ++i)
{
for (int j = 0; j < G.vexnum; ++j)
{
if (j != G.vexnum - 1)
{
if (G.arcs[i][j] != MaxInt)
{
cout << G.arcs[i][j] << "\t";
}
else
{
cout << "∞" << "\t";
}
}
else
{
if (G.arcs[i][j] != MaxInt)
{
cout << G.arcs[i][j] << endl;
}
else
{
cout << "∞" << endl;
}
}
}
}
cout << endl;
break;
case 3:
cout << "深度优先遍历的结果为:" << endl;
DFSTraverse(G);
cout << endl;
break;
case 4:
cout << "广度优先遍历的结果为:" << endl;
BFSTraverse(G);
cout << endl;
break;
default:cout << "已退出程序!" << endl; break;
}
} while (k != 5);
return 0;
}
图的代码实现
最新推荐文章于 2023-05-03 23:43:23 发布