邻接矩阵
利用二维数组的下标,将i映射为出发点,将j映射为目标点,在arr[i][j]中存储权值等信息,如果两点间没有任何关系初始化arr[i][j]为无穷。于是可以将图的关系存入二维数组中。
邻接矩阵存图优势:
1、支持有向图无向图
2、支持带边权和不带边权
3、支持自环
4、适合处理稠密图
邻接矩阵存图缺点:
1、浪费空间(空间复杂度o(n^2))、不适合处理稀疏图
测试数据:
3
4 4
1
2
3
4
1 4
5
2 4
6
1 3
7
2 3
5
输出结果:
2147483647 2147483647 7 5
2147483647 2147483647 5 6
7 5 2147483647 2147483647
5 6 2147483647 2147483647
代码:
#include<iostream>
#include<climits>
#include<string>
#include<cstdlib>
using namespace std;
#define ERROR -1
#define MAX_VERTEX_NUM 20 //最多顶点个数
#define INFINITY INT_MAX //最大值
typedef enum { DG, DN, UDG, UDN } GraphKind; //有向图、有向网、无向图、无向网
typedef int VRType, Status;
typedef string VertexType;
typedef struct ArcCell {
VRType adj; //VRType是顶点关系类型。对无权图用0
//表示相邻否;对带权图则为权值类型
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
AdjMatrix arcs; //邻接矩阵
int vexnum, arcnum; //图的当前顶点数和弧数
int kind;
}MGraph;
//根据映射定位下标
int LocateVex(MGraph G, VertexType v)
{
for (int i = 0; i < G.vexnum; i++) {
if (v == G.vexs[i]) return i;
}
return ERROR;
}
Status CreateDG(MGraph& G)//有向图
{
cout << "请输入顶点数和弧数:\n";
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入向量信息:\n";
cin >> G.vexs[i];
}
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
G.arcs[i][j].adj = INFINITY;
}
}
VertexType v, u; // 出发点 目标点
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入第" << k + 1 << "条弧的信息(v,u):\n";
cin >> v >> u;
int i = LocateVex(G, v);
int j = LocateVex(G, u);
G.arcs[i][j].adj = 1;
}
return 1;
}
Status CreateDN(MGraph& G)//有向网
{
cout << "请输入顶点数和弧数:\n";
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入向量信息:\n";
cin >> G.vexs[i];
}
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
G.arcs[i][j].adj = INFINITY;
}
}
VertexType v, u; // 出发点 目标点
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入第" << k + 1 << "条弧的信息(v,u):\n";
cin >> v >> u;
int i = LocateVex(G, v);
int j = LocateVex(G, u);
cout << "请输入包含的额外信息(边权):\n";
cin >> G.arcs[i][j].adj;
}
return 1;
}
Status CreateUDG(MGraph& G)//无向图
{
cout << "请输入顶点数和弧数:\n";
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入向量信息:\n";
cin >> G.vexs[i];
}
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
G.arcs[i][j].adj = INFINITY;
}
}
VertexType v, u; // 出发点 目标点
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入第" << k + 1 << "条弧的信息(v,u):\n";
cin >> v >> u;
int i = LocateVex(G, v);
int j = LocateVex(G, u);
G.arcs[i][j].adj = G.arcs[j][i].adj = 1;
}
return 1;
}
Status CreateUDN(MGraph& G)//无向网
{
cout << "请输入顶点数和弧数:\n";
cin >> G.vexnum >> G.arcnum;
for (int i = 0; i < G.vexnum; i++) {
cout << "请输入第" << i + 1 << "向量信息:\n";
cin >> G.vexs[i];
}
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
G.arcs[i][j].adj = INFINITY;
}
}
VertexType v, u; // 出发点 目标点
int w; // 权重
for (int k = 0; k < G.arcnum; k++) {
cout << "请输入第" << k + 1 << "条弧的信息(v,u):\n";
cin >> v >> u;
int i = LocateVex(G, v);
int j = LocateVex(G, u);
cout << "请输入包含的额外信息(边权):\n";
cin >> G.arcs[i][j].adj;
G.arcs[j][i].adj = G.arcs[i][j].adj;
}
return 1;
}
Status CreateGraph(MGraph& G)
{
cin >> G.kind;
switch (G.kind)
{
case DG:return CreateDG(G);
case DN:return CreateDN(G);
case UDG:return CreateUDG(G);
case UDN:return CreateUDN(G);
default: return ERROR;
}
}//CreateGraph
void TraveGraph(MGraph G)
{
for (int i = 0; i < G.vexnum; i++) {
for (int j = 0; j < G.vexnum; j++) {
cout << G.arcs[i][j].adj << ' ';
}
cout << '\n';
}
}
int main()
{
MGraph G;
cout << "请输入要创建的图的类型(有向图 0、有向网 1、无向图 2、无向网 3):\n";
CreateGraph(G);
TraveGraph(G);
return 0;
}