1. 图的数组表示法
2. 代码
#include "ds.h"
// 图的数组(邻接矩阵)存储表示
#define INFINITY INT_MAX // 用整型最大值代替∞
#define MAX_VERTEX_NUM 26 // 最大顶点个数
#define MAX_NAME 5 // 顶点字符串的最大长度+1
#define MAX_INFO 20 // 相关信息字符串的最大长度+1
typedef int VRType; // 顶点关系类型
typedef char InfoType; // 相关信息类型
typedef char VertexType[MAX_NAME]; // 顶点类型
enum GraphKind{DG, DN, UDG, UDN};// {有向图,有向网,无向图,无向网}
typedef struct
{
VRType adj; // 顶点关系类型。对无权图,用1(是)或0(否)表示相邻否;对带权图,则为权值
InfoType *info; // 该弧相关信息的指针(可无)
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 二维数组
struct MGraph
{
VertexType vexs[MAX_VERTEX_NUM]; // 顶点向量
AdjMatrix arcs; // 邻接矩阵
int vexnum, arcnum; // 图的当前顶点数和弧数
GraphKind kind; // 图的种类标志
};
Boolean visited[MAX_VERTEX_NUM]; // 访问标志数组(全局量)
void(*VisitFunc)(VertexType); // 函数变量
typedef VRType QElemType; // 队列元素类型
//队列的链式存储结构
typedef struct QNode{
QElemType data;
struct QNode *next;
}*QueuePtr;
typedef struct LinkQueue{
QueuePtr front, rear;
}LinkQueue;
// 带头结点的单链队列
void InitQueue(LinkQueue &Q);
void DestroyQueue(LinkQueue &Q);
void ClearQueue(LinkQueue &Q);
Status QueueEmpty(LinkQueue Q);
int QueueLength(LinkQueue Q);
Status GetHead(LinkQueue Q, QElemType &e);
void EnQueue(LinkQueue &Q, QElemType e);
Status DeQueue(LinkQueue &Q, QElemType &e);
// 带头结点的单链队列
void InitQueue(LinkQueue &Q)
{
Q.front = (QueuePtr)malloc(sizeof(QNode));
if (!Q.front) exit(OVERFLOW);
Q.front->next = NULL;
Q.rear = Q.front;
}
void DestroyQueue(LinkQueue &Q)
{
QueuePtr q, p = Q.front;
while (p)
{
q = p->next;
free(p);
p = q;
}
Q.front = Q.rear = NULL;
}
void ClearQueue(LinkQueue &Q)
{
QueuePtr q, p = Q.front->next;
while (p)
{
q = p->next;
free(p);
p = q;
}
Q.front->next = NULL;
Q.rear = Q.front;
}
Status QueueEmpty(LinkQueue Q)
{
if (Q.front == Q.rear)
return TRUE;
else
return FALSE;
}
int QueueLength(LinkQueue Q)
{
int i = 0;
QueuePtr p = Q.front->next;
while (p)
{
i++;
p = p->next;
}
return i;
}
Status GetHead(LinkQueue Q, QElemType &e)
{
if (Q.front->next)
{
memcpy(&e, &(Q.front->next->data), sizeof(QElemType));
return OK;
}
else
{
return FALSE;
}
}
void EnQueue(LinkQueue &Q, QElemType e)
{
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if (!p) exit(OVERFLOW);
p->next = NULL;
memcpy(&(p->data), &e, sizeof(QElemType));
Q.rear->next = p;
Q.rear = p;
}
Status DeQueue(LinkQueue &Q, QElemType &e)
{
QueuePtr p = Q.front, q;
if (Q.front == Q.rear)
return FALSE;
q = p->next;
memcpy(&e, &(q->data), sizeof(QElemType));
p->next = q->next;
if (Q.rear == q)
Q.rear = Q.front;
free(q);
return OK;
}
// 图的数组(邻接矩阵)存储(存储结构由c7-1.h定义)的基本操作(21个),包括算法7.1、
// 7.2、算法7.4~7.6
// 初始条件:图G存在,u和G中顶点有相同特征
// 操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
int LocateVex(MGraph G, VertexType u)
{
int i;
for (i = 0; i < G.vexnum; ++i)
{
if (strcmp(u, G.vexs[i]) == 0)
return i;
}
return -1;
}
// 采用数组(邻接矩阵)表示法,由文件构造没有相关信息的无向图G
void CreateFUDG(MGraph &G)
{
int i, j, k;
char filename[13];
VertexType va, vb;
FILE *graphlist;
printf("请输入数据文件名(f7-1.txt或f7-2.txt):");
scanf("%s",filename);
graphlist = fopen(filename, "r"); // 打开数据文件,并以graphlist表示
fscanf(graphlist, "%d", &G.vexnum);
fscanf(graphlist, "%d", &G.arcnum);
for (i = 0; i < G.vexnum; ++i)
fscanf(graphlist, "%s", G.vexs[i]); // 构造顶点向量
for (i = 0; i < G.vexnum; ++i) // 初始化邻接矩阵
for (j = 0; j < G.vexnum; ++j)
{
G.arcs[i][j].adj = 0; // 图
G.arcs[i][j].info = NULL; // 没有相关信息
}