图的存储结构
图的逻辑结构是:多对多
图的存储方式
数组(邻接矩阵)表示法
定义
图没有顺序存储结构,但可以借助二维数组来表示元素间的关系
- 图的邻接矩阵是一个二维数组
A.arcs[n][n] 定义为:A.arcs[i][j] = 1 存在从 i 顶点到 j 顶点的弧或者边,否则 A.arcs[i][j] = 0
无向图的邻接矩阵
如下无向图
无向图
则它的邻接矩阵为
无向图的邻接矩阵
在无向图的邻接矩阵中,它的特点:
- 无向图的邻接矩阵是
对称 的 - 顶点 i 的度 = 第 i 行/列 中 1 的个数
- 完全图的邻接矩阵中,对角元素为 0 ,其余为 1
有向图的邻接矩阵
如下有向图
有向图
则它的邻接矩阵为
有向图的邻接矩阵
第 i 行含义:以节点 Vi 为尾的弧(即出度边)
第 i 列含义:以节点 Vi 为头的弧(即入度边)
在有向图的邻接矩阵中,它的特点:
- 有向图的邻接矩阵
可能是不对称 的 - 顶点的
出度 = 第 i 行元素之和 - 顶点的
入度 = 第 i 列元素之和 顶点的度 = 第 i 行元素之和 + 第 i 列元素之和
网(即有权图)的邻接矩阵表示法
定义为:A.arcs[i][j] = Wij 存在从 i 顶点到 j 顶点的弧或者边的权,否则 A.arcs[i][j] = 无穷大
如下网
有向网
则它的邻接矩阵为
有向网的邻接矩阵
邻接矩阵的存储表示
#define MAX_VERTEX_NUM 26
#define MAX_NAME 3
enum GraphKind
{
DG,
DN,
UDG,
UDN
};
typedef int VRType;
typedef char InfoType;
typedef char VertexType[MAX_NAME];
typedef struct
{
VRType adj;
InfoType *info;
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
struct MGraph
{
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
enum GraphKind kind;
};
邻接矩阵的代码实现
main.c
#include "graph.h"
int main(int argc, char *argv[])
{
printf("this is graph\r\n");
return 1;
}
graph.h
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int Boolean;
#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 26
#define MAX_NAME 3
enum GraphKind
{
DG,
DN,
UDG,
UDN
};
typedef int VRType;
typedef char InfoType;
typedef char VertexType[MAX_NAME];
typedef struct
{
VRType adj;
InfoType *info;
} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
struct MGraph
{
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
enum GraphKind kind;
};
graph.c
#include "graph.h"
int LocateVex(struct MGraph G, VertexType u)
{
int i;
for (i = 0; i < G.vexnum; ++i)
if (strcmp(u, G.vexs[i]) == 0)
return i;
return -1;
}
void CreateFUDG(struct 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");
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;
}
}
for (k = 0; k < G->arcnum; ++k)
{
fscanf(graphlist, "%s%s", va, vb);
i = LocateVex((*G), va);
j = LocateVex((*G), vb);
G->arcs[i][j].adj = G->arcs[j][i].adj = 1;
}
fclose(graphlist);
G->kind = UDG;
}
void CreateFUDN(struct MGraph *G)
{
int i, j, k, w;
char filename[13];
VertexType va, vb;
FILE *graphlist;
printf("请输入数据文件名:");
scanf("%s", filename);
graphlist = fopen(filename, "r");
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 = INFINITY;
G->arcs[i][j].info = NULL;
}
}
for (k = 0; k < G->arcnum; ++k)
{
fscanf(graphlist, "%s%s%d", va, vb, &w);
i = LocateVex(*G, va);
j = LocateVex(*G, vb);
G->arcs[i][j].adj = G->arcs[j][i].adj = w;
}
fclose(graphlist);
G->kind = UDN;
}
makefile
objects = main.o graph.o
obj: $(objects)
cc -o obj $(objects) -lm
main.o : graph.h
graph.o : graph.h
.PHONY : clean
clean :
-rm obj $(objects)
|