我们可以分为头和表结构,如图所示
/**
* 表头连接的表中结点定义
* */
typedef struct tableBody {
int vexIndex;//邻接点在数组中的位置下标
struct tableBody *nextarc;//指向下一个邻接点的指针
} tableBody;
/**
* 表头结点定义
* */
typedef struct tableHead {
char data;//顶点的数据域
struct tableBody *firstarc;//指向邻接点的指针
} tableHead, *tableHeadArr;//存储各链表头结点的数组
/**图-邻接表定义*/
typedef struct {
tableHead vertices[20];//图中顶点及各邻接点数组
int vexnum, arcnum;//记录图中顶点数和边或弧数
} LJBGraph;
内部注释涵盖了上述步骤。
void createGraph(LJBGraph *g) {
//总顶点个数,总边数
int i, j, k;
tableBody *tb;
printf("输入顶点数和边数");
scanf("%d %d", &g->vexnum, &g->arcnum);//获取顶点数和边数
//gettchar();
for (i = 0; i < g->vexnum; i++) {
char c;
printf("输入%d 个顶点值", (i + 1));
getchar();
scanf("%c", &c);
g->vertices[i].data = c; //获取顶点值,
g->vertices[i].firstarc = NULL; //将边表置为空
}
for (k = 0; k < g->arcnum; k++) {
printf("输入a,b 在图中有a-->b:");
getchar();
char a,b;
scanf("%c %c", &a, &b); //输入i,j 在图中有i-->j
tb = (tableBody *) malloc(sizeof(tableBody));
i=localIndex(g,a); //a顶点所在顶点数组中的下标值。
j=localIndex(g,b); //b顶点所在数组中的下标值。
tb->vexIndex = j;
tb->nextarc = g->vertices[i].firstarc; //头插法建立边表
g->vertices[i].firstarc = tb;//把新建的结点链接在顶点后面
/*如果为无向图,则加入以下代码
e=(EdgeNode*)malloc(sizeof(EdgeNode));
e->adjvex = i;
e->next = g->adjList[j].firstedge;
g->adjList[j].firstedge= e;*/
}
printfL(g);
DFSTraverse(g);
}
寻找下标值,就是普通的遍历,在顶点数组中遍历返回下标。
int localIndex(LJBGraph *g,char data){
for(int i=0;i<g->vexnum;i++){
if(g->vertices[i].data == data){
return i;
}
}
printf("没有这个字符");
return -1;
}
void printfL(LJBGraph *g) {
//输出图的信息
printf("表为 :\n");
tableBody *p;
printf("\n");
//邻接表不需要表标题。
int i;
for (i = 0; i < g->vexnum; i++) {
printf("%d%c\t",(i),g->vertices[i].data);//表头结点
p = g->vertices[i].firstarc;
while (p) {
printf("%d\t", p->vexIndex);//外表结点
p = p->nextarc;//外表结点下移
}
printf("\n");
}
}
是不是代码很简单,所有东西都封装起来。
int main(void) {
LJBGraph *g;
createGraph(g);
return 0;
}
存储结构 | 储存方式 | 操作特性 |
---|---|---|
邻接矩阵 | 一维数组(顶点) 二维数组(邻接关系) | 1:易于判定顶点是否邻接,查顶点的邻接点 2:插入、删除顶点复杂 |
邻接表 | 头结点(顶点) 表结点(邻接关系) | 1:易于:查询某顶点的邻接点,边或弧的插入、删除 2:判定顶点是否邻接,比邻接矩阵低效。 |