对于有n个顶点的无向图,怎样存储可以省一半空间

对于有n个顶点的无向图,怎样存储可以省一半空间,第1张

原则上的确是n的平方,不过由于无向图的邻接矩阵是一个对称矩阵,只需要存储下三角或者上三角的元素,个数就是从1加到n,就是n(n+1)/ 2,不过题目问错了,这是压缩存储,是用一维数组存放,一般好像不叫矩阵

其实更精确地说,上面的数字个数是普通对称矩阵的,这个邻接矩阵的对角线一定为0,所以,只需要存储1 加到n-1,也就是n(n-1)/2就可以了

无向图,是指在图中的每条边都是无向的,无向图G=<V,E>,其中V是非空集合,称为顶点集,E是V中元素构成的无序二元组的集合,成为边集。

如图所示,这是一张无向图

如果我们需要存储这份图,通过邻接矩阵,我们将上图表示为 :

      A          B         C        D          E         F        G

A    0          0         1         0          1         0        0

B    0          0         0         0          0         1        0 

C    1          0         0         0          1         0        0

D   0          0         0         0          0         0        1

E    1          0         1         0          0         0        0

F    0          1         0         0          0         0        1

G   0          1         0         1          0         1        0    

从这张表中,我们可以发现,无向图的邻接矩阵是根据正对角线对称的,这种情况是因为无向图不区分方向。

有了这样一个邻接矩阵后。我们就可通过矩阵,可以得到那两个顶点之间存在一条边,甚至可以通过邻接矩阵去验证一张图是否为邻接矩阵。

但是,邻接矩阵只能对简单的图进行表示,即图的边和点没有什么特殊含义,那么,如果又这样一张图:

在图中,我们可以知道这是一张无向加权图,现在如果我们需要表示这样一张图,该采用什么样的数据结构呢?

或许你可以说,我还是用邻接矩阵来存储数据,存储方式如下:

       a          b         c         d          e         f        

a    0          20         1       0        10         9       

b    20         0         5         6         0         11        

c    0           5         0         6          0         0        

d   0           6         6         0          18         14        

e    10         0        0         18         0         10        

f    9           11         0         14          10         0        

这样的话,邻接矩阵存储的值就有了多重含义,不仅仅表示两个顶点之间存在关系,还知道了存在什么样的关系,但是,情况是会不断复杂的,当我们每条边的含义不仅仅只有权重,还有了最大流通量,最小流通量等属性时,而且当我们的顶点也具有了相应的属性时(如权重),邻接矩阵就不在适用于这样的情况下了,那么,这个时候我们需要用什么样的数据结构来应对,能让它能面对复杂的情况呢?

这个时候,我们就可以考虑邻接链表了:

这是一张用于表示无向图的邻接链表,图中先将所有的顶点一次标了序号0,1,2,3,接着再链接到的节点中用标号来表示下一个节点是哪个节点,因为是无向图,所以存在重复的部分,当这个无向图的顶点需要增加新的属性时,我们只需要对节点添加一个属性即可,这样看来的话,可扩展性显然是比临街矩阵要好的,有些人可能会有这样一个疑惑,这邻接链表还是不能解决边属性增加的问题啊?针对这个问题,我们来看看下面这张图:

这张图中,邻接链表中的节点多了一个属性专门用来存储边值,这样看来的话,无论是点对象的属性增加还是变得属性增加,我们都可以通过邻接链表来实现了。

但是,真正使用过相关数据结构的朋友就会发现一个问题,当在处理问题时,可能我们经常需要获取一条边来进行 *** 作,但是在只有一个顶点的情况下,针对邻接链表获取一条边是一件很痛苦的事情,每一次获取我们都需要遍历所有与该顶点相连的边,这样的话是很消耗时间和内存的,但是邻接矩阵虽然可以随机访问,但是他不能处理复杂的业务,那究竟该怎么办呢?

纵观计算机历史中,这样的问题我们遇到了很多,向计算机 *** 作系统的页面置换算法,调度算法等,都是有连个互相在对立方面具有优势的情况(A精通A领域,但不熟悉B领域;B精通B领域,但不熟悉A领域),这样看来的话,我们可以借鉴一下先人们的解决思路,我们可以先将完整的图使用邻接链表存储,然后仅仅对点与点之间的联系使用临接矩阵进行存储,这样的话,我们就可以兼顾两者的优点,代价就是多一点空间存储邻接矩阵。到这里就结束了,整个文章就一句话总结:中庸之道。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9611860.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存