![f2ce71f3e8824232d0167abeaef45111.png](https://img-blog.csdnimg.cn/img_convert/f2ce71f3e8824232d0167abeaef45111.png)
放假在家划了几天水,补更十二月图实验。图实现手头还有其他操作算法,对代码实现有兴趣的道友可私聊交流。以上!
之后应该会更基于SAT的二进制数独游戏的实现(学校课设作业,一起学习~)。SAT问题即命题逻辑公式的可满足性问题(satisfiability problem),是计算机科学与人工智能基本问题,是一个典型的NP完全问题,可广泛应用于许多实际问题如硬件设计、安全协议验证等,具有重要理论意义与应用价值。SAT问题也是程序设计与竞赛的经典问题~
照例:“君に見せたいものがあるんだ(有件礼物想要呈现给你),幾千の星を(满天繁星)。”
4 基于邻接表的图实现
4.1 问题描述
依据最小完备性和常用性相结合的原则,以函数形式定义了创建图、销毁图、查找顶点、获得顶点值和顶点赋值等12种基本运算。按要求构造了一个具有菜单的功能演示系统,演示系统实现,图的文件形式保存,且能实现多图管理。
//
4.1.1 图的基本概念
无序积:设A,B为任意的两个集合,称{{a,b}|a∈A∧b∈B}为A与B的无序积,记作A & B。
无向图:一个无向图G是一个有序的二元组<V,E>,其中V是一个非空有穷集,称作顶点集,其元素称作顶点或结点E是无序积V & V的有穷多子集,称作边集,其元素称作无向边,简称边。(如图4-1所示)
![c5b7eba60b592dfcf3ec09915fdc3ba8.png](https://img-blog.csdnimg.cn/img_convert/c5b7eba60b592dfcf3ec09915fdc3ba8.png)
有向图:一个有向图D是一个有序的二元组<V,E>,其中V是一个非空有穷集,称作顶点集,其元素称作顶点或结点E是笛卡尔积V×V的有穷多子集,称作边集,其元素称作有向边,简称边。(如图4-2所示)
![b0cabfc8dd2debaefeaa800fe6cb5bec.png](https://img-blog.csdnimg.cn/img_convert/b0cabfc8dd2debaefeaa800fe6cb5bec.png)
图:无向图和有向图统称为图,有时用 G泛指图用V(G),E(G)分别表示G的顶点集和边集,|V(G)|,|E(G)|分别是G的顶点数和边数。顶点数称作图的阶,n个顶点的图称作n阶图。
4.1.2 邻接表的基本概念
邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对图的每个顶点建立一个容器(n个顶点建立n个容器),第i个容器中的结点包含顶点Vi的所有邻接顶点。实际上我们常用的邻接矩阵就是一种未离散化每个点的边集的邻接表。
图的邻接表存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。如词条概念图所示,表结点存放的是邻接顶点在数组中的索引。对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。
在有向图中,描述每个点向别的节点连的边;在无向图中,描述每个点所有的边(如图4-3、4-4所示)。
![aeb2fa22d2337b352d629b81496647bc.png](https://img-blog.csdnimg.cn/img_convert/aeb2fa22d2337b352d629b81496647bc.png)
![dce284e7a4fd59081c24c8d64ba32be1.png](https://img-blog.csdnimg.cn/img_convert/dce284e7a4fd59081c24c8d64ba32be1.png)
4.1.3 基本运算及其定义
以函数形式定义了创建图、销毁图、查找顶点、获得顶点值和顶点赋值等12种基本运算,具体运算功能定义。
基本操作:创建图、销毁图、查找顶点、顶点赋值、获得第一邻接点、获得下一邻接点、插入顶点、删除顶点、插入弧、删除弧、深度优先搜索遍历、广深度优先搜索遍历
函数定义名:CreateCraph(G,V,VR);DestroyGraph(G);LocateVex(G,u);PutVex (G,u,value);FirstAdjVex(G, u);NextAdjVex(G, v, w);InsertVex(G,v);DeleteVex(G,v);InsertArc(G,v,w);DeleteArc(G,v,w);DFSTraverse(G,visit());BFSTraverse(G,visit());
- 其中ElemType为数据元素的类型名,具体含义可在预定义函数头文件自行选择定义,结点类型为结构型,包含二个部分,一个是能唯一标识一个结点的关键字,另一个是值。图G中顶点关键字具有唯一性。 V和VR对应的是图的逻辑定义形式,比如V为顶点序列,VR为关键字对的序列。不能将邻接矩阵等物理结构来代替V和VR。
- 具有菜单的功能演示系统其中,在主程序中完成函数调用所需实参值的准备和函数执行结果的显示,并给出适当的操作提示显示。
4.2 系统设计
4.2.1 数据物理结构
结构实现定义(如图4-5所示):
typedef
![4e6431333cd8ba3e2ce21d5b2d2b67c7.png](https://img-blog.csdnimg.cn/img_convert/4e6431333cd8ba3e2ce21d5b2d2b67c7.png)
4.2.2 演示系统
演示系统的欢迎菜单为新建表、打开文件、退出程序三个主功能,预定义操作文件数目为多文件(可以自行修改,此处仅做多表管理示例)。打开已有文件,利用空树读取存在文件里的元素,用只读模式“r+”打开,故不改变文件本身的数据。退出程序操作实现文件和树操作的保存保证程序安全退出。(基本结构示意见图4-6)
![ee31c6a0d66b4f7fd429165c28b8d94a.png](https://img-blog.csdnimg.cn/img_convert/ee31c6a0d66b4f7fd429165c28b8d94a.png)
4.2.3 关于图和邻接矩阵
图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。⼀个⼀维数组存储图中顶点信息,⼀个⼆维数组(称为邻接矩阵)存储图中的边或弧的信息。定义以下数据结构:边集合的存储常用邻接矩阵或者邻接表。边数值(权值)表示顶点之间有某种关系,0表示两个顶点之间没有边,也即没有关系。
邻接矩阵是一个二维数组,matrix[顶点数][顶点数]。也可定义为一个省一半空间的一维数组 n(n+1)/2。
结构定义如下:
//图的邻接矩阵存储结构
附录D 基于邻接表实现图源程序
//