首先,一个图包含的元素主要有: 顶点数目,顶点值,弧的数目,弧的值(一般由两个顶点来确定),当然你也可以加入这个图的信息,比如,是有向图,还是无向图。
一般的,可以如下定义:
typedef int VRType;typedef char InfoType;typedef char VertexType[MAX_NAME];#define INFINITY INT_MAX /* 用整型最大值代替∞ */#define MAX_VERTEX_NUM 20 /* 最大顶点个数 */typedef enum{DG,DN,AG,AN}GraphKind; /* {有向图,有向网,无向图,无向网} */ typedef struct{ VRType adj; /* 顶点关系类型。对无权图,用1(是)或0(否)表示相邻否; */ /* 对带权图,c则为权值类型 */ InfoType *info; /* 该弧相关信息的指针(可无) */}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct{ VertexType vexs[MAX_VERTEX_NUM]; /* 顶点向量 */ 顶点的值 AdjMatrix arcs; /* 邻接矩阵 */ 这是弧形的邻接矩阵。当然,也可以直接写成 vrtype arcs[max_ver_num][max_ver_num]. int vexnum,arcnum; /* 图的当前顶点数和弧数 */ GraphKind kind; /* 图的种类标志 */}MGraph;
建立邻接矩阵的图的过程,实际就是写入上述结构体的一个对象的值。
void CreateMGraph(MGraph *G){ //建立无向网的邻接矩阵表示int i,j,k,w;printf("请输入无向网G的顶点数,边数,边是否含其它信息(是:1,否:0): ");scanf("%d,%d,%d",&(*G).vexnum,&(*G).arcnum,&IncInfo); printf("请输入%d个顶点的值(<%d个字符):\n",(*G).vexnum,MAX_NAME); for(i=0;i<(*G).vexnum;++i) /* 构造顶点向量 */ scanf("%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;karcnum;k++){ //读入e条边,建立邻接矩阵 scanf("%d%d%d",&i,&j,&w);//输入边(v i ,v j )上的权w //这里实际上是直接输入第几个结点之间有联系,并写入他的值。然后下面会赋值。 G->arcs[i][j]=w; G->arcs[j][i]=w;}
#####################################################//如果我们不是输入的结点,而是输入结点的值,让结点之间自动建立联系,并写入权值呢?首先:int LocateVex(MGraph G,VertexType u){ /* 初始条件:图G存在,u和G中顶点有相同特征 */ /* 操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回-1 */ int i; for(i=0;i
上述过程就是建立无向图的过程。
下面是建立有向图的过程:
建立有向图的过程的前面部分是一样的。但是在建立弧的部分有所不同
在邻接矩阵初始化完毕之后,
printf("请输入%d条弧的弧尾 弧头(以空格作为间隔): \n",(*G).arcnum); 注意,表明弧头 弧尾 for(k=0;k<(*G).arcnum;++k) { scanf("%s%s%*c",va,vb); /* %*c吃掉回车符 */ i=LocateVex(*G,va); j=LocateVex(*G,vb); (*G).arcs[i][j].adj=1; /* 有向图 * }(*G).kind=DG;
上述代码中,有的直接将弧设定为了1, 这种叫做 图, 而需要输入弧的值的, 这种就叫做网 (最上面的代码)。也就是说,图和网的区别仅仅在于弧是否带了权值。 有的为网,没有的就是图。 在实际的应用中,大部分还是网。 注意一个区别:当是图的时候,弧的权值初始化为0;但是如果是网,那么就初始化为无穷大。