图的邻接矩阵表示法&邻接表表示法

匿名 (未验证) 提交于 2019-12-03 00:36:02

图表示是一种多对多的关系的数据结构。因为线性表表示的是一种一对一的关系的数据结构,树表示的是一种一对多的数据结构,所以图把线性表和树都包含在内。图由一个非空的有限顶点集合和一个有限边集合组成。当我们描述图的时候,一定要包含以下两个元素:

1、Vertex

2、Edge

ijEdgeijVertexijji

< ij >EdgeijVertexijji

初始化一个图是,可以一条边也没有,但是不能一个顶点也没有。

那么怎么用代码表示一个图?

第一种方法是邻接矩阵表示法:即用矩阵,一个二维数组来表示一个图。

#include <stdio.h> #include <stdlib.h>  #define MaxVertex 100  /*最大顶点数*/ #define INFINITY 65535 /*双字节无符号整数的最大值*/ typedef int Vertex; /*二维数组的下标表示顶点,为整型*/ typedef int WeightType; /*边的权值的类型*/  typedef char DataType; /*顶点存储的数据类型为字符型*/  /*图的数据结构*/ typedef struct GraphNode *PtrlGraphNode; struct GraphNode { 	int numv; /*顶点数*/  	int nume; /*边数*/  	WeightType wt[MaxVertex][MaxVertex]; /*邻接矩阵*/ 	DataType Data[MaxVertex]; /*存放顶点的数据*/ 	/*很多情况下,顶点无数据,此时Data[]可以不用*/ }; typedef PtrlGraphNode Graph;/*用邻接矩阵存储的图*/

用一个二维数组来表示图中一组顶点对的关系,还有一个一维数组来存放顶点的数据。

/*边的数据结构*/ typedef struct EdgeNode *PtrlEdgeNode; struct EdgeNode { 	Vertex V1, V2; /*有向边<V1, V2>*//*无向边(V1, V2)*/ 	WeightType weight; /*权重*/ }; typedef PtrlEdgeNode Edge;

边的数据结构,一条边由一组顶点对和权重表示(即顶点对的关系)。

,

/*建立一个有VertexNum个顶点但没有边的空图*/ Graph CreatGraph(int VertexNum)  { 	Vertex i,j; 	Graph MyGraph; 	 	MyGraph=(Graph)malloc(sizeof(struct GraphNode));/*申请空间建立图*/ 	MyGraph->numv=VertexNum; 	MyGraph->nume=0; //初始化边数为0;  	 	/*对二维数组矩阵初始化*/ 	for (i=0;i<MyGraph->numv;i++) { 		for (j=0;j<MyGraph->numv;j++) { 			MyGraph->wt[i][j]=INFINITY; 		} 	} 	return MyGraph; }

CreatGraphVertexnum0

/*插入边*/ void InsertEdge(Graph MyGraph, Edge MyEdge)  { 	/*插入边<V1, V2>*/ 	MyGraph->wt[MyEdge->V1][MyEdge->V2]=MyEdge->weight; 	 	/*如果是无向图,还要加上插入边<V2, V1>*/ 	MyGraph->wt[MyEdge->V2][MyEdge->V1]=MyEdge->weight; }

V1V2

Graph BuildGraph()  { 	Graph MyGraph; /*建图*/ 	Edge MyEdge; /*建边*/  	Vertex v; 	int VertexNum,i; 	 	printf("请输入顶点个数"); 	scanf("%d", &VertexNum);  	MyGraph=CreatGraph(VertexNum);/*建立一个有numv个顶点,没有边的图*/ 	 	printf("请输入边数:"); 	scanf("%d", &MyGraph->nume);   /* 读入边数 */ 	MyEdge=(Edge)malloc(sizeof(struct EdgeNode));/*建立边结点*/ 	/*插入边:格式为:"起点->终点->权重"。插入到邻接矩阵*/  	for (i=0;i<MyGraph->nume;i++) { 		scanf("%d %d %d",&MyEdge->V1, &MyEdge->V2, &MyEdge->weight); 		InsertEdge(MyGraph, MyEdge); 	} 	 	/*如果顶点有数据,就读入数据*/ 	for (i=0;i<MyGraph->numv;i++) { 		scanf("%c", &MyGraph->Data[i]); 	} 	 	return MyGraph; }

Graph[ n ][ n ]n0n-1<  ij  >GraphGraph[ i ][ j ]=10

用邻接矩阵表示法表示出来的矩阵图,有以下特点:

1、0Graph[ n ][ n ]0

2、1221Graph[ 1 ][ 2 ]Graph[ 2 ][ 1 ]1


0110

那么如何解决邻接矩阵浪费空间和时间的问题?我们知道线性表,线性表顺序存储需要实现分配好内存,这样有可能造成空间浪费或空间不够用,于是就有了链表的方法,同样图的表示方法也可以用链表的方式,就是邻接表表示法。

邻接表表示法,即用一个链表的集合,一个一维指针数组,依然用数组下标表示顶点。所以数组的大小就是图中顶点的个数。

#include <stdio.h> #include <stdlib.h>  #define MaxVertex 100  /*最大顶点数*/ typedef int Vertex; /*顶点的下标表示顶点*/  typedef int WeightType; /*边的权值类型为整型*/ typedef char DataType; /*顶点存储的数据的类型*/  /*边的数据结构*/ typedef struct EdgeNode *PtrlEdgeNode; struct EdgeNode { 	Vertex V1, V2;  /* 向边<V1, V2>*/ 	WeightType weight; /*权重*/ }; typedef PtrlEdgeNode Edge;  /*邻接点的数据结构*/  typedef struct PointNode *PtrlPointNode; struct PointNode { 	Vertex index; /*邻接点的下标*/ 	WeightType weight; /*边的权重*/ 	PtrlPointNode Next; /*指向下一个邻接点的指针*/ };  /*顶点表头结点的数据结构*/ typedef struct HeadNode { 	PtrlPointNode HeadEdge; /*边的表头结点指针*/ 	DataType Data; /*顶点的数据*/ } PointList[MaxVertex]; /*邻接表类型*/  /*图结点的数据结构*/  typedef struct GraphNode *PtrlGraphNode; struct GraphNode { 	int numv; /*顶点数*/ 	int nume; /*边数*/ 	PointList PL; /*邻接表*/ }; typedef PtrlGraphNode  ListGraphNode; /*邻接表方式存储图*/

26291822

/*创建一个有Vertexnum个顶点但没有边的图*/ ListGraphNode CreatGraph(int Vertexnum)  { 	Vertex i; 	ListGraphNode MyGraph; 	 	MyGraph=(ListGraphNode)malloc(sizeof(struct GraphNode)); 	MyGraph->nume=0; 	MyGraph->numv=Vertexnum; 	 	for (i=0;i<MyGraph->numv;i++) { 		MyGraph->PL[i].HeadEdge=NULL; //初始化数组里各个头结点  	} 	return MyGraph; } /*插入边*/ void InsertEdge(ListGraphNode MyGraph, Edge E)  { 	PtrlPointNode Node; /*邻接点*/ 	/*插入边<V1, V2>*/ 	/*为 V2建立新的邻接点*/  	Node=(PtrlPointNode)malloc(sizeof(struct PointNode)); 	Node->index=E->V2; /*将V2插入V1的表头*/ 	Node->weight=E->weight; 	Node->Next=MyGraph->PL[E->V1].HeadEdge; 	MyGraph->PL[E->V1].HeadEdge=Node; 	 	/*如果是无向图,还要插入边<V2, V1>*/ 	Node=(PtrlPointNode)malloc(sizeof(struct PointNode)); 	Node->index=E->V1; /*将V2插入V1的表头*/ 	Node->weight=E->weight; 	Node->Next=MyGraph->PL[E->V2].HeadEdge; 	MyGraph->PL[E->V2].HeadEdge=Node; } /*创建图*/ ListGraphNode BuildGraph() { 	ListGraphNode MyGraph; 	Edge E; 	Vertex i,j,numv; 	 	printf("请输入要读入的顶点个数:"); 	scanf("%d", &numv); 	MyGraph=CreatGraph(numv); 	 	printf("请输入要读入的边数:"); 	scanf("%d", &MyGraph->nume); 	if (MyGraph->nume!=0) { 		E=(Edge)malloc(sizeof(struct EdgeNode)); /*建立边结点*/ 		/*读入边:格式为"起点 终点 权重"*/ 		for (i=0;i<MyGraph->numv;i++) { 			scanf("%d %d %d", &E->V1, &E->V2, &E->weight); 			/*插入边到图里*/ 			InsertEdge(MyGraph, E); 		} 	} 	 	/*如果顶点有数据的话,读入数据*/ 	for (i=0;i<MyGraph->numv;i++) { 		scanf("%c", &MyGraph->PL[i].Data); 	} 	return MyGraph; }

< 5, 9 >5995

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!