图的存储结构-无向邻接矩阵与无向邻接表(C语言)

邻接矩阵

概念 :图的邻接矩阵存储方式是用两个数组来表示图,一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。

无向邻接矩阵的结构定义

#include<stdio.h>
typedef char VertexType;  //顶点类型
typedef int EdgeType;  //边的权值类型
#define MAXVEX 100
#define INFINITY 65535  //表示无穷大

typedef struct {
	VertexType vexts[MAXVEX];   //顶点表
	EdgeType arc[MAXVEX][MAXVEX];   //邻接矩阵
	int numNodes, numEdges;     //图当前顶点数与边数
}MGraph;

建立无向网图的邻接矩阵

LocateVex()函数用来查找顶点

/* 建立无向网图的邻接矩阵 */
void CreateMGraph(MGraph* G)
{
	int weight;  //表示权值
	scanf("%d%d", &G->numNodes, &G->numEdges);   //输入顶点数与边数
	for (int i = 0; i < G->numNodes; i++)  //读入顶点数据,建立顶点表
		scanf(" %c", &G->vexts[i]);    

	for (int i = 0; i < G->numNodes; i++)
		for (int j = 0; j < G->numNodes; j++)
			G->arc[i][j] = INFINITY;  //邻接矩阵初始化
	//构造
	for (int k = 0; k < G->numEdges; k++)
	{
		VertexType v1, v2;
		int i, j;  //用来返回下标
		scanf(" %c %c %d", &v1, &v2, &weight);
		i = LocateVex(*G, v1);
		j = LocateVex(*G, v2);
		G->arc[i][j] = weight;  //边<v1, v2>的权值
		G->arc[j][i] = G->arc[i][j]; //边<v1, v2>的对称边同样为weight
	}
}
/* 查找顶点,返回下标 */
int LocateVex(MGraph G, VertexType e)
{
	for (int i = 0; i < G.numNodes; i++)
		if (e == G.vexts[i])
			return i;
	return -1;
}

邻接表

概念

邻接表,存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。

简单来说:给图中的各个结点独自建立一个链表,用链表存储该结点所有的邻接点以及权值,用数组与链表相结合的存储结构称为邻接表。

无向图的邻接表结构定义

#include<stdio.h>
#include<stdlib.h>
typedef char VertexType;  //顶点类型
typedef int EdgeType;    //边上权值
#define MAXVEX 100 // 最大顶点数

typedef struct EdgeNode {      //边表结点
	int adjvex;                //领接点域,存储对应下标
	EdgeType info;             //存储权值,如果是非网图可以省略
	struct EdgeNode* next;    //指向下一个邻接点
}EdgeNode;

typedef struct VertexNode {    //顶点结点
	VertexType data;           //顶点域
	EdgeNode* firstedge;      //边表头指针
}VertexNode;
typedef struct VertexNode AdjList[MAXVEX];  //邻接表类型

typedef struct {
	AdjList adjList;
	int numNodes, numEdges;   //图当前顶点数与边数
}GraphAdjList;

建立无向图的邻接表

LocateVex()函数用来查找顶点

/* 建立图的邻接表结构 */
void CreateALGRAph(GraphAdjList* G)
{
	scanf("%d%d", &G->numNodes, &G->numEdges); //输入顶点数与边数
	
	for (int i = 0; i < G->numNodes; i++)  //建立顶点表
	{
		scanf(" %c", &G->adjList[i].data);
		G->adjList[i].firstedge = NULL;       //边表置为空
	}

	for (int k = 0; k < G->numEdges; k++)   //建立边表
	{
		VertexType v1, v2;
		int i, j;  //用来返回下标
		scanf(" %c %c", &v1, &v2); //输入一条边依附的两个顶点
		i = LocateVex(*G, v1);
		j = LocateVex(*G, v2);
		
		EdgeNode* e1 = (EdgeNode*)malloc(sizeof(EdgeNode));   //生成边表结点(指针e指向生成的内存空间)
		e1->adjvex = j;         //邻接序号
		/* 头插法 */
		e1->next = G->adjList[i].firstedge; //e指向当前顶点指向结点
		G->adjList[i].firstedge = e1;    //当前顶点指向e

		EdgeNode* e2 = (EdgeNode*)malloc(sizeof(EdgeNode));   //生成边表结点
		e2->adjvex = i;         //邻接序号
		/* 头插法 */
		e2->next = G->adjList[j].firstedge;     //e指向当前顶点指向结点
		G->adjList[j].firstedge = e2;    //当前顶点指向e
	//对于无向图,一条边对应两顶点,所以上面一次对 i 和 j 插入
	}
}
/* 查找顶点 */
int LocateVex(GraphAdjList G, VertexType v)
{
	for (int i = 0; i < G.numNodes; i++)
		if (v == G.adjList[i].data)
			return i;
	return -1;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mirror_zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值