采用邻接表的方式存储图
分析:
采用邻接表相对于邻接矩阵来说更节省存储空间,这里我们需要两个数据结构:
①顶点表结构:包括顶点信息及指向第一个邻接点的头指针
②边表结构:包括该邻接点域(在数组中的下标)、权值及下一个邻接点指针
③一个数组,用于存储所有顶点,因为数组的随机存储特性,方便我们查找
④图结构:包括顶点数组及顶点数、边数
具体创建流程:
首先我们需要输入图的顶点数和边数,将其存入图结构中,并由输入的顶点数依次输入顶点信息,并将第一个邻接点的头指针
置位NULL,这是建立顶点表的流程;
其次我们需要建立边表,根据输入的边个数,依次输入边(vi,vj)的顶点序号,再采取头插法进行插入,若是无向图则需要
重复反向依次设置,至此,图的邻接表结构建立完成。
代码如下:
#define _CRT_SECURE_NO_WARNINGS
#define MAXSIZE 100
typedef struct EdgeNode {//边表结点
int index;//邻接点在数组中的下标
int weight;//权值
EdgeNode *next;//下一个邻接点
}EdgeNode;
typedef struct VertexNode {//顶点表节点
char info;//顶点信息
EdgeNode *firstNode;//顶点的第一个邻接点指针
}VertexNode, Adjlist[MAXSIZE];
typedef struct {
Adjlist adjlist;//顶点数组
int numE, numV;//边数、顶点数
}ALGraph;
#include <stdio.h>
#include <stdlib.h>
void createGraph(ALGraph *G) {
int e, v, vi, vj, w;
printf("请输入图的边数与结点数(以空格分开):");
scanf("%d %d", &e, &v);
G->numE = e;
G->numV = v;
printf("请依次输入顶点信息:\n");
for (int i = 0; i < G->numV; i++) {
printf("请输入第%d个结点信息:", i + 1);
getchar();
scanf("%c", &G->adjlist[i].info);
G->adjlist[i].firstNode = NULL;
}
printf("请输入边表信息:\n");
for (int i = 0; i < G->numE; i++) {
printf("请输入边(vi,vj)的顶点序号及其权值(以空格分开):");
scanf("%d %d %d", &vi, &vj, &w);
//若是无向图则需要两个顶点进行操作,采用头插法
EdgeNode *e = (EdgeNode *)malloc(sizeof(EdgeNode *));
e->index = vj - 1;//数组下标要减一
e->weight = w;
e->next = G->adjlist[vi - 1].firstNode;
G->adjlist[vi - 1].firstNode = e;
EdgeNode *ed = (EdgeNode *)malloc(sizeof(EdgeNode *));
ed->index = vi - 1;
ed->weight = w;
ed->next = G->adjlist[vj - 1].firstNode;
G->adjlist[vj - 1].firstNode = ed;
}
}
void dispGraph(ALGraph *G) {//将图用邻接表的形式展示出来
for (int i = 0; i < G->numV; i++) {
int j = i;
printf("%c-->", G->adjlist[j].info);
EdgeNode *p = G->adjlist[j].firstNode;
while (p) {
printf("(%d)%c-->", p->weight, G->adjlist[p->index].info);
p = p->next;
}
printf("^\n");
}
}
int main() {
ALGraph G;
createGraph(&G);
dispGraph(&G);
return 0;
}
运行结果如图:
一世浮生一刹那,一程山水一年华。余生并没那么多来日方长,只有时光匆匆。惟愿,好好爱自己,好好爱值得的人,好好为自己交上一份满意的人生答卷。