您的位置:首页 > 其它

图的表示法

2016-06-13 21:58 246 查看
要表示一个图G=(V,E)(注:V:vertex、E:edge),有两种方法,即邻接表和邻接矩阵。这两种方法既可以用于有向图,也可以用于无向图

// 图1,无向图
1 ----- 2
|       |  \
|       |  / 3
5 ----- 4


邻接表

邻接表表示法通常表示稀疏图(图中 |E| 远小于 |V|^2)比较紧凑。

// 邻接表数据结构表示无向图

// 定义图中最多100个节顶点
#define MAX 100

// 邻接表中的顶点定义
typedef struct Vertex
{
int v;
struct Vertex *next;

} Vertex;

// 邻接表
Vertex Adj[MAX];

// 创建顶点
Vertex* makeVertex(int v)
{
Vertex *pVertex = (Vertex*) malloc(sizeof(Vertex));
pVertex->v = v;
pVertex->next = NULL;
return pVertex;
}
// 删除顶点
void destroyVertex(Vertex *pVertex)
{
free(pVertex);
}


// 完整代码
#include <stdio.h>
#include <malloc.h>

#define MAX 100

typedef struct Vertex
{
int v;
struct Vertex *next;

} Vertex;

Vertex Adj[MAX];

Vertex* makeVertex(int v)
{
Vertex *pVertex = (Vertex*) malloc(sizeof(Vertex));
pVertex->v = v;
pVertex->next = NULL;
return pVertex;
}
void destroyVertex(Vertex *pVertex)
{
free(pVertex);
}

// 初始化图
void initGraph()
{
printf("input edges:\nlike 1,2\n-1,-1\n");
int v1 = 0, v2 = 0;
while (1){
scanf("%d,%d", &v1, &v2);

// 输入-1,-1表示输入结束
if (v1 == -1 && v2 == -1)
break;

Adj[v1].v = v1;
Vertex *pVertex = &Adj[v1];
while ( pVertex->next ) {
pVertex = pVertex->next;
}
pVertex->next = makeVertex(v2);
}
}

// 打印当前图
void printGraph(int n)
{
for (int i = 1; i <= n; i++) {
printf("%d", Adj[i].v);
Vertex *pVertex = Adj[i].next;
while (pVertex) {
printf("--%d", pVertex->v);
pVertex = pVertex->next;
}
printf("\n");
}
}
// 销毁图中的节点
void uninitGraph(int n) {
for (int i = 1; i <= n; i++) {
Vertex *pVertex = Adj[i].next;
Adj[i].next = NULL;
while (pVertex) {
Vertex *pTemp = pVertex->next;
destroyVertex(pVertex);
pVertex = pTemp;
}
printf("destroy vertex[%d]\n", i);
}
}

int main()
{
int n = 0;
printf("input vertex's number\n");
scanf("%d", &n);

initGraph();
printGraph(n);
uninitGraph(n);
printGraph(n);
return 0;
}

// 执行方式
input vertex's number
5
1,2
1,5
...
-1,-1 // 结束输入


邻接表的长度

若G是一个有向图,则所有邻接表的长度之和为 |E|。

若G是一个无向图,则所有邻接表的长度之和为 2|E|。

无论有向图还是无向图,邻接表需要的存储空间为O(V+E)。

加权图

图的每条边有着相应权值。

设G=(V,E)是一个加权函数为w的加权图。对每一条边(u,v)且(u,v)属于E,权值为w(u,v)和顶点v一起存储在u的邻接表中。

typedef struct Vertex
{
int v; // 顶点
int w; // 加权值
struct Vertex *next;

} Vertex;


邻接矩阵

邻接矩阵表示法通常用于表示稠密图(图中|E| 接近于 |V|^2)或必须很快判别两个顶点是否存在连接边时使用

// 邻接矩阵表示无向图

#define MAX 100

int  G[MAX][MAX] = {0};


// 完整代码

#include <stdio.h>

#define MAX 100

int  G[MAX][MAX] = {0};

// 初始化图
void initGraph()
{
printf("input edges:\nlike 1,2\n");
int v1 = 0, v2 = 0;
while (1){
scanf("%d,%d", &v1, &v2);

if (v1 == -1 && v2 == -1)
break;

G[v1][v2] = 1;
G[v2][v1] = 1;
}

}

// 打印图
void printGraph(int n)
{
for (int i = 1; i <= n; i++) {
printf("%d", i);
for (int j = 1; j <= n; j++) {
if (G[i][j] == 1) {
printf("--%d", j);
}
}
printf("\n");
}
}

int main()
{
int n = 0;
printf("input vertex's number\n");
scanf("%d", &n);

initGraph();
printGraph(n);

return 0;
}


邻接矩阵的特点

一个图的邻接矩阵表示需要占用O(V^2)的存储空间,它与图中的边数多少是无关的。

无向图的邻接矩阵A就是它自己的转置矩阵:A=A^T。在某些应用中只需要存储临街觉着呢的对角线及对角线以上的部分,图所占的存储空间几乎可以减少一半。

邻接矩阵的也可以用来表示加权图。矩阵中相应的元素可以存储边的权值,如果边不存在就用0或无限大的值来表示权值。

如果一个图不是加权的,邻接矩阵的每个元素只用一个二进制位,而不必用一个字的空间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: