图的存储可以采用邻接矩阵和邻接表,如下,该图有五个顶点,七条边。
邻接表采用数组和链表完成,数组用于存储顶点的元素,也就是图中的1-5,结构体AGraph里面包含v-节点个数,e-边的条数;
typedef struct AGraph
{
int v,e;
VNode adjlist[max_size];
}AGraph;
每一个数组元素的类型为节点类型,节点类型的结构体里面包括data-节点的值,firstarc-第一条边指向的地址;
typedef struct VNode
{
int data;
ArcNode *firstarc;
}VNode;
firstarc的类型为ArcNode-边,其中包括边所指向的节点-adjvex,以及指向下一条边的节点地址。
typedef struct ArcNode
{
int adjvex;
struct ArcNode *nextarc;
}ArcNode;
创建时首先循环输入节点,再循环输入边,因为是有向图,所以直接用数组下标定位到v1->v2中的v1 ,将这条边插在v1所在的位置--采用链表的插入方式。输出时直接输出即可。
void CreatA(AGraph *g)
{
//首先创建一个只有节点没有边的图
printf("请输入节点个数\n");
scanf("%d",&(g->v));
int i,j;
for(i=0;i<g->v;i++)
{
printf("请输入第%d个顶点\n",i+1);
scanf("%d",&(g->adjlist[i].data));
g->adjlist[i].firstarc=NULL;
}
//插入边
printf("请输入边的数量\n");
scanf("%d",&(g->e));
int v1,v2;
ArcNode *a;
printf("请输入边 例如 v1->v2 (由v1指向v2)\n");
for(j=0;j<g->e;j++)
{
printf("请输入第%d条边\n",j+1);
scanf("%d %d",&v1,&v2);
a->adjvex=v2;
a->nextarc=g->adjlist[v1-1].firstarc;
g->adjlist[v1-1].firstarc=a;
}
}
完整代码
#include <stdio.h>
#define max_size 10
typedef struct ArcNode
{
int adjvex;
struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode
{
int data;
ArcNode *firstarc;
}VNode;
typedef struct AGraph
{
int v,e;
VNode adjlist[max_size];
}AGraph;
void CreatA(AGraph *g)
{
//首先创建一个只有节点没有边的图
printf("请输入节点个数\n");
scanf("%d",&(g->v));
int i,j;
for(i=0;i<g->v;i++)
{
printf("请输入第%d个顶点\n",i+1);
scanf("%d",&(g->adjlist[i].data));
g->adjlist[i].firstarc=NULL;
}
//插入边
printf("请输入边的数量\n");
scanf("%d",&(g->e));
int v1,v2;
ArcNode *a;
printf("请输入边 例如 v1->v2 (由v1指向v2)\n");
for(j=0;j<g->e;j++)
{
printf("请输入第%d条边\n",j+1);
scanf("%d %d",&v1,&v2);
a->adjvex=v2;
a->nextarc=g->adjlist[v1-1].firstarc;
g->adjlist[v1-1].firstarc=a;
}
}
void print(AGraph *g)
{
int i;
ArcNode *p;
for(i=0;i<g->v;i++)
{
printf("%d->",g->adjlist[i].data);
p=g->adjlist[i].firstarc;
while(p)
{
printf("%d->",p->adjvex);
p=p->nextarc;
}
}
}
int main()
{
AGraph g;
CreatA(&g);
print(&g);
return 0;
}
不对的地方欢迎指正,谢谢。