图的邻接矩阵实现
逻辑结构分为两部分:V和E集合。因此,用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵。邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵
邻接矩阵(Adjacency Matrix):是表示顶点之间相邻关系的矩阵。设G=(V,E)是一个图,其中V={v1,v2,…,vn}。G的邻接矩阵是一个具有下列性质的n阶方阵:
①对无向图而言,邻接矩阵一定是对称的,而且主对角线一定为零(在此仅讨论无向简单图),副对角线不一定为0,有向图则不一定如此。
②在无向图中,任一顶点i的度为第i列(或第i行)所有非零元素的个数,在有向图中顶点i的出度为第i行所有非零元素的个数,而入度为第i列所有非零元素的个数。
③用邻接矩阵法表示图共需要n^2个空间,由于无向图的邻接矩阵一定具有对称关系,所以扣除对角线为零外,仅需要存储上三角形或下三角形的数据即可,因此仅需要n(n-1)/2个空间。
代码实现
#include "graph.h"
#include <stdlib.h>
/*
typedef char VTYPE; //顶点元素的值
typedef int ETYPE; //边的值 权重 \ 连通
enum GraphKind{DG,DN,UDG,UDN};
typedef struct Arc{
VTYPE beg; //边起始顶点
VTYPE end; //边结束顶点
ETYPE weight; //权重 1连通
}Arc;
typedef struct MGraph{
VTYPE * vexs; //存储所有顶点的值 VTYPE vexs[MAX_VEXNUM];
ETYPE *matrix; //ETYPE matrix[MAX_VEXNUM][MAX_VEXNUM];
size_t vexnum;
size_t arcnum;
GraphKind kind;
}MGraph;
*/
//通过顶点的值查找该顶点所在的下标位置
static int find_vexs_index(MGraph *pg,VTYPE val){
size_t i;
for(i=0;i<pg->vexnum;i++){
if(pg->vexs[i] == val){
return i;
}
}
return -1;
}
//MGraph g;
int graph_init(MGraph* pg,VTYPE vexs[],size_t vexnum,
Arc arc[],size_t arcnum,GraphKind kind){
pg->vexnum = vexnum;
pg->vexs = (VTYPE*)malloc(sizeof(VTYPE)*vexnum);
if(pg->vexs==NULL){
return -1;
}
//ETYPE (*p)[vexnum];
pg->matrix = (ETYPE*)malloc(sizeof(ETYPE)*vexnum*vexnum);
memset(pg->matrix,0,sizeof(ETYPE)*vexnum*vexnum);
if(pg->matrix==NULL){
free(pg->vexs);
return -1;
}
size_t i,j;
for(i=0;i<vexnum;i++){
pg->vexs[i] = vexs[i];
}
ETYPE (*arr)[vexnum] = (ETYPE (*)[vexnum])pg->matrix;
for(i=0;i<arcnum;i++){
int begi = find_vexs_index(pg,arc[i].beg);
int endi = find_vexs_index(pg,arc[i].end);
arr[begi][endi] = arc[i].weight;
if(kind == UDG || kind == UDN){
arr[endi][begi] = arc[i].weight;
}
}
pg->arcnum = arcnum;
pg->kind = kind;
return 0