首先,一个图包含的元素主要有: 顶点数目,顶点值,弧的数目,弧的值(一般由两个顶点来确定),当然你也可以加入这个图的信息,比如,是有向图,还是无向图。
一般的,可以如下定义:
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;k<G->arcnum;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<G.vexnum;++i)
if(strcmp(u,G.vexs[i])==0)
return i;
return -1;
}然后,上面读入e条边,建立邻接矩阵的过程就是:for(k=0;k<(*G).arcnum;++k)
{
scanf("%s%s",va,vb);
i=LocateVex(*G,va);
j=LocateVex(*G,vb);
(*G).arcs[i][j].adj=(*G).arcs[j][i].adj=1; /* 无向图 */
}
(*G).kind=AG;
}//CreateMGraph
上述过程就是建立无向图的过程。
下面是建立有向图的过程:
建立有向图的过程的前面部分是一样的。但是在建立弧的部分有所不同
在邻接矩阵初始化完毕之后,
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;但是如果是网,那么就初始化为无穷大。