Bootstrap

数据结构——图的数组(邻接矩阵)表示法

数组表示无向图

用两个数组(vexs[],arcs[][])分别存储数据元素(顶点)的信息和数据元素之间的关系(边或弧)的信息。以二维数组表示有n个顶点的图时,需存放n个顶点信息和n^2个弧信息存储量。若考虑无向图的邻接矩阵的对称性,则可采用压缩存储的方式只存入矩阵的下三角(或上三角)元素。下示算法时在邻接矩阵存储结构MGraph上对图构造的实现框架,它根据G的种类调用具体构造的算法。例如G为无向图则调用CreatUDN()。本篇只实现了无向图的构建后续将实现DG、DN、及UDG。

以下图为例:

顶点数组:

邻接矩阵:

 

 

 C语言实现

/*
文件名:ArrayNotation.c
描述:图的数组表示法
时间:2018/11/19
		2019.1.3补全
*/


#include<stdio.h>

//-------------图的数组(邻接矩阵)存储表示---------------
#define INFINITY 95533	// 最大值
#define MAX_VERTEX_NUM 20	//最大顶点个数
#define VRType int		//顶点关系类型,对无权图,用1或0表示相邻否;对带权图,则为权值类型
#define InfoType int	// ?弧类型??????
#define VErtexType int	//图顶点类型
typedef enum {DG,DN,UDG,UDN}GraphKind;	//图的种类(有向图,有向网,无向图,无向网)****枚举类型enum
typedef struct ArcCell {
	VRType adj;		//顶点关系类型
	InfoType *info;	//该弧相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct {
	VErtexType vexs[MAX_VERTEX_NUM];	//顶点向量
	AdjMatrix arcs;		//邻接矩阵
	int vexnum, arcnum;		//图的当前顶点数和弧数
	GraphKind	kind;		//图的种类标志
}MGraph;


int LocateVex(MGraph *G, VRType point)	//确定某个顶点在图G中的位置
{
	int i, j;
	for (i = 0; i < G->vexnum; i++)
		if (G->vexs[i] == point)
			return i;

}//LocateVex


void CreatUDN(MGraph *G)	//采用数组(邻接矩阵),构造无向网G
{
	int i, j, k;
	VRType origin, terminus, weight; 	//边的起点,终点,权值
	printf("输入图的顶点数 弧数");
	scanf("%d %d", &(G->vexnum), &(G->arcnum));
	for (i = 0; i < G->vexnum; i++)	//将顶点值存储进去
	{
		printf("输入顶点值:");
		scanf("%d", &(G->vexs[i]));
	}//for
	for (i = 0; i < G->vexnum; i++)	//初始化邻接矩阵
		for (j = 0; j < G->vexnum; j++)
		{
			G->arcs[i][j].adj = INFINITY;
			G->arcs[i][j].info = NULL;
		}//for
	for (k = 0; k < G->arcnum; k++)	//	arcnum???弧数
	{
		printf("输入一条边的两端以及权值");
		scanf("%d %d %d", &origin, &terminus ,&weight);
		i = LocateVex(G, origin);	//利用LocateVex函数确定起点(origin)及终点(terminus)在G中位置
		j = LocateVex(G, terminus);
		G->arcs[i][j].adj = 0;
		G->arcs[j][i].adj = 0;
		G->arcs[i][j].info = (InfoType *)malloc(sizeof(InfoType));
		G->arcs[j][i].info = (InfoType *)malloc(sizeof(InfoType));
		*(G->arcs[i][j].info) = weight;
		*(G->arcs[j][i].info) = weight;
	}//for
	printf("创建成功\n");
}//CreatUDN

void CreatDG(MGraph *G)		//有向图
{
	int i, j, k;
	VRType origin, terminus; 	//边的起点,终点
	printf("输入图的顶点数 弧数");
	scanf("%d %d", &(G->vexnum), &(G->arcnum));
	for (i = 0; i < G->vexnum; i++)	//将顶点值存储进去
	{
		printf("输入顶点值:");
		scanf("%d", &(G->vexs[i]));
	}//for
	for (i = 0; i < G->vexnum; i++)	//初始化邻接矩阵
		for (j = 0; j < G->vexnum; j++)
		{
			G->arcs[i][j].adj = INFINITY;
			G->arcs[i][j].info = NULL;
		}//for
	for (k = 0; k < G->arcnum; k++)	//	arcnum???弧数
	{
		printf("输入一条边的起点终点");
		scanf("%d %d", &origin, &terminus);
		i = LocateVex(G, origin);	//利用LocateVex函数确定起点(origin)及终点(terminus)在G中位置
		j = LocateVex(G, terminus);
		G->arcs[i][j].adj = 0;
		G->arcs[i][j].info = (InfoType *)malloc(sizeof(InfoType));
	}//for
	printf("创建成功\n");

}

void CreatDN(MGraph *G)		//有向网
{
	int i, j, k;
	VRType origin, terminus, weight; 	//边的起点,终点,权值
	printf("输入图的顶点数 弧数");
	scanf("%d %d", &(G->vexnum), &(G->arcnum));
	for (i = 0; i < G->vexnum; i++)	//将顶点值存储进去
	{
		printf("输入顶点值:");
		scanf("%d", &(G->vexs[i]));
	}//for
	for (i = 0; i < G->vexnum; i++)	//初始化邻接矩阵
		for (j = 0; j < G->vexnum; j++)
		{
			G->arcs[i][j].adj = INFINITY;
			G->arcs[i][j].info = NULL;
		}//for
	for (k = 0; k < G->arcnum; k++)	//	arcnum???弧数
	{
		printf("输入一条边的起点终点以及权值");
		scanf("%d %d %d", &origin, &terminus, &weight);
		i = LocateVex(G, origin);	//利用LocateVex函数确定起点(origin)及终点(terminus)在G中位置
		j = LocateVex(G, terminus);
		G->arcs[i][j].adj = 0;
		G->arcs[i][j].info = (InfoType *)malloc(sizeof(InfoType));
		*(G->arcs[i][j].info) = weight;
	}//for
	printf("创建成功\n");
}//CreatUDN


void CreatUDG(MGraph *G)	//无向图
{
	int i, j, k;
	VRType origin, terminus; 	//边的起点,终点
	printf("输入图的顶点数 弧数");
	scanf("%d %d", &(G->vexnum), &(G->arcnum));
	for (i = 0; i < G->vexnum; i++)	//将顶点值存储进去
	{
		printf("输入顶点值:");
		scanf("%d", &(G->vexs[i]));
	}//for
	for (i = 0; i < G->vexnum; i++)	//初始化邻接矩阵
		for (j = 0; j < G->vexnum; j++)
		{
			G->arcs[i][j].adj = INFINITY;
			G->arcs[i][j].info = NULL;
		}//for
	for (k = 0; k < G->arcnum; k++)	//	arcnum???弧数
	{
		printf("输入一条边的两端");
		scanf("%d %d", &origin, &terminus);
		i = LocateVex(G, origin);	//利用LocateVex函数确定起点(origin)及终点(terminus)在G中位置
		j = LocateVex(G, terminus);
		G->arcs[i][j].adj = 0;
		G->arcs[j][i].adj = 0;
	}//for
	printf("创建成功\n");

}

void CreatGraph(MGraph *G)		//采用数组(邻接矩阵)表示法构造图G
{
	int kind;
	printf("输入图类型(1.DG/2.DN/3.UDG/4.UDN):");
	scanf("%d", &kind);
	switch (kind)
	{
	case 1: CreatDG(G);	break;
	case 2: CreatDN(G);	break;
	case 3:CreatUDG(G);	break;
	case 4:CreatUDN(G);	break;
	default: printf("ERROR!"); break;
	}//switch
}//CreatGraph
		
int main()
{
	MGraph G;
	CreatGraph(&G);

	return 0;
}

运行结果:

存在问题:

c语言枚举类型的应用 

 

 

 

 

;