图的存储之邻接表(C语言)

邻接表

  邻接表主要由两部分构成,数组和链表,数组主要用来存顶点信息,链表是用来存与顶点相连的其他顶点的信息。数组分为两部分,一部分是顶点信息,一部分是个指针,用来指向链表的头。链表也是分为两部分,一部分是顶点的下标,一部分是指针。
数组内部的信息定义如下:
这里将顶点类型定义为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;
}

测试点信息如下:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值