图的邻接表存储及求邻接点操作
1、任务描述
本关任务:要求从文件(本测试文件为lt.txt等文件由平台提供,开发者可以自行查看)输入顶点和边数据,包括顶点信息、边、权值等,编写程序实现以下功能。
1)构造图G的邻接表和顶点集,即图的存储结构为邻接表。
2)输出图G的各顶点和邻接表。
3)输出图G中某个顶点的所有邻接顶点。
注意图在这里分了四类:
(a)无向图
(b)有向图
(c)无向网
(d)有向网
2、相关知识
对于图来说,邻接矩阵是不错的一种图存储结构,但是对于边数相对顶点较少的图,这种结构对存储空间浪费极大。
因此考虑另外一种存储结构方式:邻接表,即数组与链表相结合的存储结构。
在图的邻接表结构中,用一个连续存储区域来存储图中各顶点的数据,并对图中每个顶点vi建立一个单链表(称为vi的邻接表),把顶点vi的所有相邻顶点(即后继结点)的序号链接起来。
第i个单链表中的每一个结点(也称为表结点)均含有三个域:邻接点域、链域和数据域,邻接点域用来存放与顶点vi相邻接的一个顶点的序号,链域用来指向下一个表结点,数据域info存储边的信息(如果边上没有权值,可以省略该info数据域)
另外每个顶点vi设置了表头结点,除了存储本身数据的数据域data外,还设置了一个链域firstarc,作为邻接表的表头指针,指向第一个表结点。n个顶点用一个一维数组表示。如图所示。
表结点的类型定义如下:
typedef struct
{int adjvex; // 该弧所指向的顶点的位置int info; // 网的权值ArcNode *nextarc; // 指向下一条弧的指针
}ArcNode;
头结点的类型定义如下:
typedef struct
{VertexType data; // 顶点信息ArcNode *firstarc; // 第一个表结点的地址,指向第一条依附该顶点的弧的指针
}VNode,AdjList[MAX_VERTEX_NUM];
图的邻接表存储表示,类型定义如下:
typedef struct
{AdjList vertices;int vexnum,arcnum; // 图的当前顶点数和弧数 GraphKind kind; // 图的种类标志
}ALGraph;
邻接表具有如下性质:
-
图的邻接表表示不是唯一的,它与表结点的链入次序有关,取决于建立邻接表的算法以及边的输入次序;
-
无向图的邻接表中第i个边表的结点个数即为第i个顶点的度;
-
有向图的邻接表中第i个出边表的结点个数即为第i个顶点的出度,有向图的逆邻接表中第i个入边表的结点个数即为第i个顶点的入度;
-
无向图的边数等于邻接表中边表结点数的一半,有向图的弧数等于邻接表的出边表结点的数目,也等于逆邻接表的入边表结点的数目。
3、编程要求
根据提示,在右侧编辑器补充代码,要求从文件中输入顶点和边数据,包括顶点信息、边、权值等,编写函数实现图的基本运算:
void CreateGraphF(ALGraph &G); // 采用邻接表存储结构,由文件构造没有相关信息图或网G
void Display(ALGraph G); // 输出图的邻接表G
int LocateVex(ALGraph G,VertexType u); //若G中存在顶点u,则返回该顶点在图中位置;否则返回-1
int FirstAdjVex(ALGraph G,VertexType v); // 返回v的第一个邻接顶点的序号;否则返回-1
int NextAdjVex(ALGraph G,VertexType v,VertexType w);//v是图G中某个顶点,w是v的邻接顶点,返回v的(相对于w的)下一个邻接顶点的序号
4、测试说明
平台会对你编写的代码进行测试:
测试输入:
3
lt.txt
徐州
5、预期输出
无向网
8个顶点:
北京 天津 郑州 徐州 武汉 上海 株洲 南昌
9条弧(边):
北京→郑州 :695 北京→天津 :137
天津→徐州 :674 天津→北京 :137
郑州→武汉 :534 郑州→徐州 :349 郑州→北京 :695
徐州→上海 :651 徐州→郑州 :349 徐州→天津 :674
武汉→株洲 :409 武汉→郑州 :534
上海→徐州 :651 上海→南昌 :825
株洲→南昌 :367 株洲→武汉 :409
南昌→上海 :825 南昌→株洲 :367
上海 郑州 天津
输出说明:
第一行输出图的类型。
第二行起输出图的顶点和边的数据信息。
最后一行为徐州的邻接点。