邻接表
邻接表主要由两部分构成,数组和链表,数组主要用来存顶点信息,链表是用来存与顶点相连的其他顶点的信息。数组分为两部分,一部分是顶点信息,一部分是个指针,用来指向链表的头。链表也是分为两部分,一部分是顶点的下标,一部分是指针。
数组内部的信息定义如下:
这里将顶点类型定义为char型,这个指针是指向链表的,所以是链表类型的
typedef struct VertexNode {
char data;
EdgeNode* firstzedge;
}Vertex;
链表的定义如下:
因为链表中的顶点信息存的是数组的下标,所以是int型
typedef struct EdgeNode {
int adjvex;//邻接点域,存储该顶点对应的下标
struct EdgeNode* next;//链域,指向下一个邻接点
}EdgeNode;
图的定义如下:
typedef struct {
Vertex adjList[100];
int numV, numE;//图中当前顶点数和边数
}Graph;
接下来就是创建图,创建图要知道顶点数和边数,还要知道边所连接的两个顶点的数组下标,这两个顶点一个是在链表中,一个是在数组中
void CreatALGraph(Graph* G) {
int i, j, k;
EdgeNode* e;//链表结点类型的指针
printf("请输入顶点的数量和边的数量:\n");
scanf("%d %d", &G->numV, &G->numE);
//输入数组信息
for (i = 0; i < G->numV; i++) {
printf("请输入顶点信息:\n");
rewind(stdin);
scanf("%c", &G->adjList[i].data);
G->adjList[i].firstedge = NULL;//将边表置为空表
}
//输入链表信息
for (j = 0; j < G->numE; j++) {
printf("请输入第%d条边对应的两个顶点的序号:\n", j);
rewind(stdin);
//这里指的是数组下标,也可以是顶点的信息,
//然后根据locate函数找到数组下标,
//locate函数在前面的邻接矩阵中讲过
scanf("%d %d", &i, &k);
//由于创建的是无向图,所以一条边对应的就是两个顶点
//所以在一次循环中针对i,k分别进行了插入
e = (EdgeNode*)malloc(sizeof(EdgeNode));
e->adjvex = i;
e->next = G->adjList[k].firstedge;
G->adjList[k].firstedge = e;
e = (EdgeNode*)malloc(sizeof(EdgeNode));
e->adjvex = k;
e->next = G->adjList[i].firstedge;
G->adjList[i].firstedge = e;
}
}
接下来就是输出
int main(void) {
int i;
Graph G;
EdgeNode* p;//先定义一个结构体类型的指针
CreatALGraph(&G);
for (i = 0; i < G.numV; i++) {
p = G.adjList[i].firstedge;
printf("%c相连的顶点有:", G.adjList[i].data);
while (p != NULL) {
//这里是p所指向的结点的adjvex值表示数组下标,
//所以要输出的还是数组所对应的数据
printf("%c ", G.adjList[p->adjvex].data);
p = p->next;
}
printf("\n");
}
return 0;
}
接下来就是完整的代码
#include<stdio.h>
#include<malloc.h>
//链表结构
typedef struct EdgeNode {
int adjvex;//邻接点域,存储该顶点对应的下标
struct EdgeNode* next;//链域,指向下一个邻接点
}EdgeNode;
//数组结构
typedef struct VertexNode {
char data;
EdgeNode* firstedge;
}Vertex;
//图的结构
typedef struct {
Vertex adjList[100];
int numV, numE;//图中当前顶点数和边数
}Graph;
void CreatALGraph(Graph* G) {
int i, j, k;
EdgeNode* e;
printf("请输入顶点的数量和边的数量:\n");
scanf("%d %d", &G->numV, &G->numE);
//输入数组信息
for (i = 0; i < G->numV; i++) {
printf("请输入顶点信息:\n");
rewind(stdin);
scanf("%c", &G->adjList[i].data);
G->adjList[i].firstedge = NULL;
}
//输入链表信息
for (j = 0; j < G->numE; j++) {
printf("请输入第%d条边对应的两个顶点的序号:\n", j);
rewind(stdin);
scanf("%d %d", &i, &k);
e = (EdgeNode*)malloc(sizeof(EdgeNode));
e->adjvex = i;
e->next = G->adjList[k].firstedge;
G->adjList[k].firstedge = e;
e = (EdgeNode*)malloc(sizeof(EdgeNode));
e->adjvex = k;
e->next = G->adjList[i].firstedge;
G->adjList[i].firstedge = e;
}
}
int main(void) {
int i;
Graph G;
EdgeNode* p;
CreatALGraph(&G);
for (i = 0; i < G.numV; i++) {
p = G.adjList[i].firstedge;
printf("%c相连的顶点有:", G.adjList[i].data);
while (p != NULL) {
printf("%c ", G.adjList[p->adjvex].data);
p = p->next;
}
printf("\n");
}
return 0;
}
测试点信息如下: