实现图的邻接矩阵和邻接表存储
题目描述
1.内容:编写一个程序graph.cpp,设计带权图的邻接矩阵与邻接表的创建了一个图,并在此基础上设计一个主程序exp8-1.cpp完成以下功能。
(1)建立如图8.1所示的有向图G的邻接矩阵,并输出它。
(2)建立如图8.1所示的有向图G的邻接表,并输出它。
(3)销毁图G的邻接表。
2.算法:得到graph.cpp程序,其中包含如下函数。
· CreateMat(MatGraph &g,int A[MAXV][MAXV],int n,int e):由边数组A、顶点数n和边数e创建图的邻接矩阵g。
· DispMat(MatGraph g):输出邻接矩阵g。
· CreateAdj(AdjGraph * &G,int A[MAXV][MAXV],int n,int e):由边数组A
顶点数n和边数e创建图的邻接表G。
· DispAdj(AdjGraph *G):输出邻接表G。
· DestroyAdi(AdiGraph *&G):销毁图的邻接表G和输一个带权有向图G
运行代码
graph.cpp
#include <stdio.h>
#include <stdlib.h> // 使用stdlib.h替换malloc.h,更符合标准规范
#include<malloc.h>
#define INF 32767
#define MAXV 100
typedef char InfoType;
// 顶点类型结构体,包含顶点编号和顶点其他信息
typedef struct {
int no;
InfoType info;
} VertexType;
// 邻接矩阵表示的图结构体类型
typedef struct {
int edges[MAXV][MAXV]; // 邻接矩阵数组,用于存储边的信息
int n; // 顶点数
int e; // 边数
VertexType vexs[MAXV]; // 存放顶点信息的数组
} MatGraph;
// 邻接表中边表结点结构体类型
typedef struct ANode {
int adjvex; // 该边的邻接点编号
struct ANode* nextarc; // 指向下一个边表结点的指针
int weight; // 边的权值(这里假设图带权,如果是无权图可根据情况修改用途或去掉)
} ArcNode;
// 邻接表头结点结构体类型,代表每个顶点的边链表头
typedef struct VNode {
InfoType info; // 顶点的其他信息
int count;
ArcNode* firstarc; // 指向第一条依附该顶点的边的指针
} VNode;
// 邻接表表示的图结构体类型
typedef struct {
VNode adjlist[MAXV]; // 邻接表头结点数组,每个元素对应一个顶点的边链表头
int n; // 顶点数
int e; // 边数
} AdjGraph;
// 创建图的邻接矩阵的函数
void createMat(MatGraph &g, int A[MAXV][MAXV], int n, int e) {
int i, j;
g.n = n;
g.e = e;
// 初始化邻接矩阵,将所有元素先设为INF(表示无穷,即无边相连)
for (i = 0; i < g.n; i++) { // 此处使用n更合理,避免使用未初始化的g->n
for (j = 0; j < g.n; j++) {
g.edges[i][j] = INF;
}
}
// 根据传入的二维数组A的值,填充邻接矩阵
for (i = 0; i < g.n; i++) {
for (j = 0; j < g.n; j++) {
g.edges[i][j] = A[i][j];
}
}
}
// 输出邻接矩阵的函数
void dispMat(const MatGraph g) { // 添加const修饰,表明函数不会修改传入的结构体内容
int i, j;
for (i = 0; i < g.n; i++) {
for (j = 0; j < g.n; j++) {
if (g.edges[i][j] != INF) {
printf("%4d", g.edges[i][j]);
}
else {
printf("%4s","∞");
}
}
printf("\n");
}
}
// 创建图的邻接表的函数
void createAdj(AdjGraph*& G, int A[MAXV][