图(Graph)——图的存储结构

前言

由于图的术语比较多,大部分的术语和实际编程可能没有什么关系,所以我这里只记录有必要的术语,其他的术语我简单地列在最后。如果想要具体了解图的话,可以去看看《大话数据结构》这本书籍。然后我会分两篇博客来记录图,这篇博客主要记录图的两种存储结构,下一篇是有关图的各种算法。图也是我比较少用的数据结构,以前学的时候学不懂,现在回头再看,能够get到里面许多点了。

图的定义

图是一种比较复杂的数据结构,他的结点之间的关系可以是任意的,图中的任意两个数据元素之间都可能相关。下图展示了图的结构:
图的结构
下面给出图的定义:

图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V, E),其中G表示一个图,V是图G中顶点的集合,E是图G中的边的集合。

我们将图的数据元素称为顶点(Vertex),并且图的顶点集合一定是有穷且非空的,即图可以没有边,但一定不能没有顶点(至少有一个)。 在图中,任意两个顶点之间都可能有关系,顶点之间的关系用边来表示。

图的分类

图的分类有很多种,这里主要依据边的无向和有向,将图分为无向图有向图

  • 无向边: 若顶点vi到vj之间没有方向,则称这条边为无向边(Edge),用无序偶对(vi, vj)来表示。
  • 有向边:若顶点vi到vj之间有方向,则称这条边为有向边,也称为弧(Arc)。用有序偶对<vi, vj>来表示有向边,vj是弧头, vi是弧尾,即该边的方向是vi–> vj(注意不要把头和尾弄反了)。

别的分类还有简单图、复杂图、稀疏图、稠密图,具体参照书去了解。在存储结构上稍微有点区别的就只有无向图和有向图了,所以这里就抛开别的术语,单纯讲讲这两种图的区别。

无向图

顶点与顶点之间没有指向关系,或者说一条边描述了两个顶点间具有双向关系。具体的例子有朋友圈、地铁路线图等。下图为无向图:
无向图

有向图

顶点与顶点之间有明确的指向关系,或者说一条边只描述了两个顶点之间具有一个单向的关系。具体的例子有微博的关注列表、食物链、程序的函数依赖图等。下图为有向图:
有向图

图的两种存储结构

图相比起线性表和树,在存储方面上复杂了许多。如果说还像链表或者树那样,用一个结点和指向下一个结点的指针来作为顶点的结构,这是不合理的。因为一个图并没有明确的头结点或者根节点,顶点与顶点之间也没有明确的顺序关系或者层次关系,所以这样的存储结构是不合理的。

而且就算采用了这样的存储结构,由于顶点之间的关系是不明确的,一个顶点可能与多个顶点有关系,也可能没有关系。这样在设计下一个顶点指针的时候只能用一个可变数组来维护(有点类似与多叉树),但这样的设计不仅难以维护,操作起来也不太方便。

在前人的不屑努力下,总结出了五种比较适合图的存储结构。但这里只介绍两种比较常用的,感兴趣的话可以去参考书籍。下面罗列出这五种存储结构:

  • 邻接矩阵
  • 邻接表
  • 十字链表
  • 邻接多重表
  • 边集数组

邻接矩阵

图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。一个一维数组存储图中的顶点信息,一个二维数组(称为邻接矩阵)来存储图中的便或弧的信息。 用上面的无向图做例子,那么他的存储结构应该是这样子的:

一维数组:

0 1 2 3
A B C D

二维数组(邻接矩阵):

0 1 2 3
0 0 1 1 1
1 1 0 1 0
2 1 1 0 1
3 1 0 1 0

一维数组是顶点到矩阵行列下标的一个映射,真正用来表示关系(边或弧)的是这个矩阵。

可以看到,在矩阵上面,行表示顶点,列表示边。比如A跟B、C、D有关系,所以0行上的1、2、3列被设为了1&#

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值