图的四种存储结构
因为图的任意两个顶点间都可能存在联系,因此无法通过数据元素在存储区中的物理位置来表示元素之间的关系,即图没有顺序存储结构,但是我们可以用二维数组(矩阵)来表示元素之间的关系——邻接矩阵。除此之外还有链式存储结构,包括邻接表、十字链表和邻接多重表。在这些方法中,邻接矩阵和邻接表最常用。
一、邻接矩阵法
图的邻接矩阵的存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息(可分别称他们为顶点数组和边数组)。设图G有n个顶点,则邻接矩阵是一个nxn的方阵。在无向图中,求某个顶点的度,即计算此顶点vi在邻接矩阵中第i行(或第i列)的元素之和。若vi到vj之间有通路,则记为1,反之为0。在有向图中,求某个顶点vi的出度,即求此顶点所在行的元素之和,若求某个顶点的如度,即求顶点所在列的元素之和。
存储空间:
无向图:n(n-1)/2
有向图(网):n^2
二、邻接链表法
对图中的每个顶点建立一个单链表,存储该顶点所有邻接顶点及其相关信息。每一个单链表设有一个表头结点。第i个单链表中的结点依附于顶点Vi的边。在求无向图的度时,只要找出此节点对应的单链表中的节点个数之和即可。但是就有向图而言,其又分为入度和出度,在邻接表中,结点vi对应的单链表中,其表示的是以vi为起点的所能到达的节点,即其对应的结点总数为此节点的出度。要想求起入度,则需要建立逆邻接表(如布简历逆邻接表,则需要扫描整个邻接表才能得出),此时,vi对应的单链表表示的是以vi为终点,以单链表中的结点作为起点的通路,故单链表中的结点总数表示的是vi的入度。
存储空间:
无向图:n+2e
有向图:n+e
三、十字链表法
对于有向图来说,邻接表虽然解决了出度问题,但是如果我们想要计算入度时则需要遍历整个图才能知道结果。而逆邻接表,它虽然解决了入度问题,但是他计算出度时又很不易。因此十字链表法应运而生,他将邻接表和逆邻接表相结合,从而时的出度和入度的计算变得容易起来。
十字链表是有向图的另一种链式存储结构,其顶点和弧分别各用一种存储结构的结点表示。弧头相同的弧被链在同一链表上,弧尾相同的弧也被链在同一链表上,链表的头结点就是顶点结点。是有向图的邻接表与逆邻接表结合起来的一种链表。在十字链表中容易找到以vi(vi∈G(V))为弧尾或弧头的弧,容易求顶点的入度和出度。
四、多重链表法
邻接多重链表是无向图的另一种链式存储结构。其顶点和弧分别各用一种存储结构的结点表示。依附于相同顶点的边被链在同一链表上,每条边依附于两个结点,所以每个边结点被同时链接在两个单链表中。链表的头结点就是顶点结点。此外,还在边结点中增加了一个标志位。用以标记该条边是否被搜索过,避免了同一条边的重复搜索。对无向图而言,邻接表的缺点:每一条边(va,vb)有两个结点,分别在第a和第b个单链表中,这可能会给边的搜索、删除等操作带来了不便。邻接多重表与邻接表的区别仅在于,同一条边,在邻接表中要用两个结点表示,而在邻接多重表中只需要一个结点。
十字链表和多重链表分别是对有向图邻接表和无向图邻接表的补充