一、图的存储结构
1.1 邻接矩阵
图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。
设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:
看一个实例,下图左就是一个无向图。
从上面可以看出,无向图的边数组是一个对称矩阵。所谓对称矩阵就是n阶矩阵的元满足aij = aji。即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的。
从这个矩阵中,很容易知道图中的信息。
(1)要判断任意两顶点是否有边无边就很容易了;
(2)要知道某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
(3)求顶点vi的所有邻接点就是将矩阵中第i行元素扫描一遍,arc[i][j]为1就是邻接点;
而有向图讲究入度和出度,顶点vi的入度为1,正好是第i列各数之和。顶点vi的出度为2,即第i行的各数之和。
若图G是网图,有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:
这里的wij表示(vi,vj)上的权值。无穷大表示一个计算机允许的、大于所有边上权值的值,也就是一个不可能的极限值。下面左图就是一个有向网图,右图就是它的邻接矩阵。
图的邻接矩阵表示法(C语言实现)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #define MaxVertexNum 100 #define INFINITY 65535 typedef char VertexType; typedef int EdgeType; enum GraphType { DG, UG, DN, UN };
typedef struct { VertexType Vertices[ MaxVertexNum ]; EdgeType Edges[ MaxVertexNum ][ MaxVertexNum ];
int n, e; enum GraphType GType; } MGraph; void CreateMGraph ( MGraph *G ) { int i, j, k, w; G-> GType = UN; printf( "请输入顶点数和边数(输入格式为:顶点数, 边数):\n" ); scanf( "%d, %d",&(G->n), &(G->e) ); printf("请输入顶点信息(输入格式为:顶点号<CR>):\n"); for ( i = 0; i < G->n; i++ ) scanf( "%c",&(G-> Vertices[i]) ); for ( i = 0; i < G->n; i++ ) for ( j = 0; j < G->n; j++ ) G->Edges[i][j] = INFINITY; printf( "请输入每条边对应的两个顶点的序号和权值,输入格式为:i, j, w:\n" ); for ( k = 0; k < G->e; k++ ) { scanf("%d,%d,%d ",&i, &j, &w); G->Edges[i][j] = w; G->Edges[j][i] = w; } }
|
图的邻接表表示法(C语言实现)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #define MaxVertexNum 100 enum GraphType { DG, UG, DN, UN };
typedef struct node{ int AdjV; struct node *Next; } EdgeNode; typedef char VertexType; typedef struct Vnode{ VertexType Vertex; EdgeNode *FirstEdge; } VertexNode; typedef VertexNode AdjList[ MaxVertexNum ]; typedef struct{ AdjList adjlist; int n, e; enum GraphType GType; } ALGraph; void CreateALGraph( ALGraph *G ) { int i, j, k; EdgeNode *edge; G-> GType = DG; printf( "请输入顶点数和边数(输入格式为:顶点数,边数):\n" ); scanf( "%d,%d", &(G->n), &(G->e) ); printf( "请输入顶点信息(输入格式为:顶点号<CR>):\n" ); for ( i=0; i < G->n; i++ ) { scanf( " %c", &(G->adjlist[i].Vertex) ); G->adjlist[i].FirstEdge = NULL; } printf( "请输入边的信息(输入格式为: i, j <CR>):\n" ); for ( k=0; k < G->e; k++ ){ scanf( "\n%d,%d", &i, &j); edge = (EdgeNode*)malloc(sizeof(EdgeNode)); edge->AdjV = j; edge->Next = G->adjlist[i].FirstEdge; G->adjlist[i].FirstEdge = edge; } }
|