图的存储结构——邻接表法

图的存储结构——邻接表法

一、邻接表

​ 由顶点表和边表构成,顶点表由顶点域(data)和指向第一条邻接边的指针(firstarc)构成,边表(邻接表)结点由邻接点域(adjvex)和指向下一条邻接边的指针域(next)构成。

二、代码实现

(1)图的邻接表存储结构定义

#define MaxVertexNum 30
typedef char VertexType;
typedef int ArcValue;

// 边表 结点
typedef struct ArcNode {
	int adjvex;				//邻接结点,该顶点对应的下标
	ArcValue value;			//权值
	struct ArcNode* next;	//链域指向下一个结点
}ArcNode;

//顶点表结点
typedef struct VertexNode {
	VertexType data;		//存储 顶点的数据
	ArcNode* firstarc;		//边表头指针
}VertexNode,AdjList[MaxVertexNum];

//邻接表
typedef struct graph {
	AdjList adjList;		//邻接表 数组
	int verNum, arcNum;		//当前定点数、边数
}GraphAdjList;

(2)创建邻接表

​ 创建顶点表及边表,如若为有向图,结点只插入一次。无向图则插入两次,顶点为双向关联。

void CreateAdjListGraph(GraphAdjList* G) {
	printf("有向图 1,无向图0:");
	int flag = 0;
	scanf("%d", &flag);
	//初始化邻接表
	for (int i = 0; i < MaxVertexNum; i++) {
		G->adjList[i].firstarc = NULL;
	}

	printf("输入顶点、边个数(空格间隔):");
	scanf("%d%d", &G->verNum, &G->arcNum);
	/*建立顶点表*/
	
	for (int i = 0; i < G->verNum; i++) {
		
		printf("请输入第%d个顶点的元素:", i + 1);
		fflush(stdin);
		scanf(" %c", &G->adjList[i].data);
		G->adjList[i].firstarc = NULL;
	}

	/*建立边表*/
	int vi, vj;
	ArcValue value;
	for (int i = 0; i < G->arcNum; i++) {
		printf("请输入vi vj w(空格间隔):");
		scanf("%d%d%d", &vi, &vj, &value);
		ArcNode* newNode;
		newNode = (ArcNode*)malloc(sizeof(ArcNode));
		newNode->next = G->adjList[vi - 1].firstarc;
		newNode->adjvex = vj;
		newNode->value = value;
		G->adjList[vi - 1].firstarc = newNode;
        
		if (flag==0) {//判断是否为有向图
			ArcNode* newNode2;
			newNode2 = (ArcNode*)malloc(sizeof(ArcNode));
			newNode2->next = G->adjList[vj - 1].firstarc;
			newNode2->adjvex = vi;
			newNode2->value = value;
			G->adjList[vj - 1].firstarc = newNode2;
		}
        
	}
}


(3)打印输出邻接表

void PrintGraphVertex(GraphAdjList* G) {
	printf("结点:\n");
	for (int i = 0; i < G->verNum; i++) {

		printf("%d\t%c\t", i+1, G->adjList[i].data);
		ArcNode* p = G->adjList[i].firstarc;
		while (p!=NULL) {
			printf("(%d,%d)\t", p->adjvex,p->value);
			p = p->next;
		}
		if (p==NULL) {
			printf("^");
		}
		printf("\n\n");
	}
}

三、完整代码

#include<stdio.h>
#include<stdlib.h>

#define MaxVertexNum 30
typedef char VertexType;
typedef int ArcValue;

// 边表 结点
typedef struct ArcNode {
	int adjvex;				//邻接结点,该顶点对应的下标
	ArcValue value;			//权值
	struct ArcNode* next;	//链域指向下一个结点
}ArcNode;

//顶点表结点
typedef struct VertexNode {
	VertexType data;		//存储 顶点的数据
	ArcNode* firstarc;		//边表头指针
	
}VertexNode,AdjList[MaxVertexNum];

//邻接表
typedef struct graph {
	AdjList adjList;		//邻接表 数组
	int verNum, arcNum;		//当前定点数、边数
}GraphAdjList;

void CreateAdjListGraph(GraphAdjList* G) {
	printf("有向图 1,无向图0:");
	int flag = 0;
	scanf("%d", &flag);

	for (int i = 0; i < MaxVertexNum; i++) {
		G->adjList[i].firstarc = NULL;
	}

	printf("输入顶点、边个数(空格间隔):");
	scanf("%d%d", &G->verNum, &G->arcNum);
	/*建立顶点表*/
	
	for (int i = 0; i < G->verNum; i++) {
		
		printf("请输入第%d个顶点的元素:", i + 1);
		fflush(stdin);
		scanf(" %c", &G->adjList[i].data);
		G->adjList[i].firstarc = NULL;
	}

	/*建立边表*/

	int vi, vj;
	ArcValue value;
	
	for (int i = 0; i < G->arcNum; i++) {
		printf("请输入vi vj w(空格间隔):");
		scanf("%d%d%d", &vi, &vj, &value);
		ArcNode* newNode;
		newNode = (ArcNode*)malloc(sizeof(ArcNode));
		newNode->next = G->adjList[vi - 1].firstarc;
		newNode->adjvex = vj;
		newNode->value = value;
		G->adjList[vi - 1].firstarc = newNode;
		if (flag==0) {
			ArcNode* newNode2;
			newNode2 = (ArcNode*)malloc(sizeof(ArcNode));
			newNode2->next = G->adjList[vj - 1].firstarc;
			newNode2->adjvex = vi;
			newNode2->value = value;
			G->adjList[vj - 1].firstarc = newNode2;
		}
	}

}


void PrintGraphVertex(GraphAdjList* G) {
	printf("结点:\n");
	for (int i = 0; i < G->verNum; i++) {

		printf("%d\t%c\t", i+1, G->adjList[i].data);
		ArcNode* p = G->adjList[i].firstarc;
		while (p!=NULL) {
			printf("(%d,%d)\t", p->adjvex,p->value);
			p = p->next;
		}
		if (p==NULL) {
			printf("^");
		}
		printf("\n\n");
	}
}


int main() {
	GraphAdjList* G;
	G = (GraphAdjList*)malloc(sizeof(GraphAdjList));
	CreateAdjListGraph(G);
	PrintGraphVertex(G);
}
  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值