本文是[数据结构基础系列(7):图]中第4课时[图的邻接矩阵存储结构及算法]和第5课时[图的邻接表存储结构及算法],并为后续内容的实践提供支持。
图的存储结构主要包括邻接矩阵和邻接表,本算法库提供存储结构的定义,以及用于构造图存储结构、不同结构的转换及显示的代码。算法库采用程序的多文件组织形式,包括两个文件:
1.头文件:graph.h,包含定义图数据结构的代码、宏定义、要实现算法的函数的声明;
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#define MAXV 100
#define INF 32767
typedef int InfoType;
typedef struct
{
int no;
InfoType info;
} VertexType;
typedef struct
{
int edges[MAXV][MAXV];
int n,e;
VertexType vexs[MAXV];
} MGraph;
typedef struct ANode
{
int adjvex;
struct ANode *nextarc;
InfoType info;
} ArcNode;
typedef int Vertex;
typedef struct Vnode
{
Vertex data;
int count;
ArcNode *firstarc;
} VNode;
typedef VNode AdjList[MAXV];
typedef struct
{
AdjList adjlist;
int n,e;
} ALGraph;
void ArrayToMat(int *Arr, int n, MGraph &g);
void ArrayToList(int *Arr, int n, ALGraph *&);
void MatToList(MGraph g,ALGraph *&G);
void ListToMat(ALGraph *G,MGraph &g);
void DispMat(MGraph g);
void DispAdj(ALGraph *G);
#endif
2.源文件:graph.cpp,包含实现各种算法的函数的定义
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
void ArrayToMat(int *Arr, int n, MGraph &g)
{
int i,j,count=0;
g.n=n;
for (i=0; i<g.n; i++)
for (j=0; j<g.n; j++)
{
g.edges[i][j]=Arr[i*n+j];
if(g.edges[i][j]!=0 && g.edges[i][j]!=INF)
count++;
}
g.e=count;
}
void ArrayToList(int *Arr, int n, ALGraph *&G)
{
int i,j,count=0;
ArcNode *p;
G=(ALGraph *)malloc(sizeof(ALGraph));
G->n=n;
for (i=0; i<n; i++)
G->adjlist[i].firstarc=NULL;
for (i=0; i<n; i++)
for (j=n-1; j>=0; j--)
if (Arr[i*n+j]!=0)
{
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->info=Arr[i*n+j];
p->nextarc=G->adjlist[i].firstarc;
G->adjlist[i].firstarc=p;
}
G->e=count;
}
void MatToList(MGraph g, ALGraph *&G)
{
int i,j;
ArcNode *p;
G=(ALGraph *)malloc(sizeof(ALGraph));
for (i=0; i<g.n; i++)
G->adjlist[i].firstarc=NULL;
for (i=0; i<g.n; i++)
for (j=g.n-1; j>=0; j--)
if (g.edges[i][j]!=0)
{
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->info=g.edges[i][j];
p->nextarc=G->adjlist[i].firstarc;
G->adjlist[i].firstarc=p;
}
G->n=g.n;
G->e=g.e;
}
void ListToMat(ALGraph *G,MGraph &g)
{
int i,j;
ArcNode *p;
g.n=G->n;
g.e=G->e;
for (i=0; i<g.n; i++)
for (j=0; j<g.n; j++)
g.edges[i][j]=0;
for (i=0; i<G->n; i++)
{
p=G->adjlist[i].firstarc;
while (p!=NULL)
{
g.edges[i][p->adjvex]=p->info;
p=p->nextarc;
}
}
}
void DispMat(MGraph g)
{
int i,j;
for (i=0; i<g.n; i++)
{
for (j=0; j<g.n; j++)
if (g.edges[i][j]==INF)
printf("%3s","∞");
else
printf("%3d",g.edges[i][j]);
printf("\n");
}
}
void DispAdj(ALGraph *G)
{
int i;
ArcNode *p;
for (i=0; i<G->n; i++)
{
p=G->adjlist[i].firstarc;
printf("%3d: ",i);
while (p!=NULL)
{
printf("-->%d/%d ",p->adjvex,p->info);
p=p->nextarc;
}
printf("\n");
}
}
3.在同一项目(project)中建立一个源文件(如main.cpp),编制main函数,完成相关的测试工作。 例:
#include <stdio.h>
#include <malloc.h>
#include "graph.h"
int main()
{
MGraph g1,g2;
ALGraph *G1,*G2;
int A[6][6]=
{
{0,5,0,7,0,0},
{0,0,4,0,0,0},
{8,0,0,0,0,9},
{0,0,5,0,0,6},
{0,0,0,5,0,0},
{3,0,0,0,1,0}
};
ArrayToMat(A[0], 6, g1);
printf(" 有向图g1的邻接矩阵:\n");
DispMat(g1);
ArrayToList(A[0], 6, G1);
printf(" 有向图G1的邻接表:\n");
DispAdj(G1);
MatToList(g1,G2);
printf(" 图g1的邻接矩阵转换成邻接表G2:\n");
DispAdj(G2);
ListToMat(G1,g2);
printf(" 图G1的邻接表转换成邻接邻阵g2:\n");
DispMat(g2);
printf("\n");
return 0;
}