图的数组(邻接矩阵)存储表示
- 代码实现(C语言)
- 定义邻接矩阵
// ----- 图的数组(邻接矩阵)存储表示 -----
typedef int VRType; //顶点关系类型,无权图用1或0表示相邻否,带权图则为权值类型
typedef char* InfoType; //弧/边相关信息
typedef int VertexType;
#define INFINITY INT_MAX //最大值∞
#define MAX_VERTEX_NUM 20 //最大顶点个数
typedef enum{DG,DN,UDG,UDN}GraphKind; //{有向图,有向网,无向图,无向网}
typedef struct ArcCell{
VRType adj; // 顶点关系类型
InfoType *info; // 指向该弧相关信息的指针
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //用二维数组表示邻接矩阵
typedef struct{
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
AdjMatrix arcs; //邻接矩阵(一个二维数组)
int vexnum,arcnum; //图的当前顶点数和弧数
GraphKind kind; // 图的类型
}MGraph;
- 邻接矩阵表示法图示
adj 标记图中此弧/边是否相连或此弧/边的权值 |
Info 指向与此边相关的信息的指针 |
ArcCell(0 0) 一号结点到一号结点的环 |
ArcCell(0 1) 一号结点到二号结点的弧/边 |
ArcCell(0 2) 一号结点到三号结点的弧/边 |
ArcCell(1 0) 二号结点到一号结点的弧/边 |
ArcCell(1 1) 二号结点到二号结点的环 |
ArcCell(1 2) 二号结点到三号结点的弧/边 |
ArcCell(2 0) 三号结点到一号结点的弧/边 |
ArcCell(2 1) 三号结点到二号结点的弧/边 |
ArcCell(2 2) 三号结点到三号结点的环 |
vexs数组 记录结点信息 |
arcs邻接矩阵 记录弧/边 |
vexnum,arcnum 图的结点数&弧/边数 |
kind 有向图/有向网/无向图/无向网 |
- 图的构造函数
#define OK 1
#define ERROR 0
typedef int Status;
Status CreateGraph(MGraph* G)
{
scanf("%d",&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;
}
}
// 无向网构造函数
Status CreateUDN(MGraph *G)
{
int IncInfo;
int i,j,k;
int v1,v2,weight;
scanf("%d %d %d",&G->vexnum,&G->arcnum,&IncInfo); // IncInfo为0则各边不含其他信息
for (i=0;i<G->vexnum;i++)
scanf("%d",&G->vexs[i]); //构造顶点向量(约定第一个结点为1,...第n个节点为n)
for (i=0;i<G->vexnum;i++) // 初始化邻接表
for (j=0;j<G->vexnum;j++)
{
G->arcs[i][j].adj=INFINITY; // adj=INFINITY表示不存在边
G->arcs[i][j].info=NULL; // 每条弧/边不存在额外信息,指针初始化为NULL
}
for (k=0;k<G->arcnum;k++) // 更新边信息
{
scanf("%d %d %d",&v1,&v2,&weight); // 输入边连接的两点以及此边的权值
i=v1-1;j=v2-1; // 第v1个结点到第v2个结点的边在邻接表中的位置
G->arcs[i][j].adj=weight; // 为边赋权
if (IncInfo) scanf("%s",G->arcs[i][j].info); // 若边存在额外信息,输入额外信息
G->arcs[j][i]=G->arcs[i][j]; // 无向图,将边双向化
}
return OK;
} // CreateUDN
/*有向图/网以及无向图的构造函数算法与上述无向网构造函数类似,仅需要在双向化&为边/弧赋权处略作改动即可*/
- 构造函数的时间复杂度分析(n条边&e个顶点)
- 初始邻接表O(n^2)
- 输入结点信息O(e)
- 输入边信息O(n)
- T(n)=O(n^2)
应用场景
- 通过邻接表容易判断两结点是否邻接O(1)
- 容易求各个结点的度O(e)