图
1.图是什么?
图是一种非线形的数据结构,比树更加复杂。
图中的元素叫做顶点(vertex),图中的一个顶点可以和任意一个顶点建立联系,之间的联系就叫做
边(edge),每个顶点有多少边,叫做这个顶点的度(degree)。
像微博、微信、qq等交友软件,存储关注的粉丝,好友,好友的亲密度等都是用的图这种数据结构存储的。
2.无向图
微信中的好友就可以用无向图来存储。下图就是一个无向图。连个人相互加好友就在两个人之间建立了一条边。如下图所示,就是一个无向图。但是微博就不可以,以为微博可以单方面的关注。所以就需要有向图了。
3.有向图
在有向图中分为入度和出度的概念,入度就是有多少顶点指向他,出度就是他有指向多少顶点。拿微博的粉丝来说入度就是他有多少粉丝,而出度就是他关注了多少人。
下图就是有方向的图,还是拿微博来举例子,假如A关注了E,而E没有关注A 就如下图所示,A会指向E,而E不会指向A。
4.带权图
对于qq中好友的亲密度我们会发现以上的两种图都解决不了这种情况,就引入了一个新的图的类型,带权图。
带权图的每一条边都有一个权重(weight),可以通过这个权重来表示好友的亲密度。
5.图的存储方法
a.邻接矩阵
邻接矩阵的底层依赖于一个二维数组。
无向图邻接矩阵存储
如下图所示,利用一个二维数组存储图的二维数组如下:
x
=
{
0
1
1
1
1
0
0
1
1
0
0
1
1
1
1
0
}
x=\left\{ \begin{matrix} 0&1&1&1\\ 1&0&0&1\\ 1&0&0&1\\ 1&1&1&0\\ \end{matrix} \right\}
x=⎩⎪⎪⎨⎪⎪⎧0111100110011110⎭⎪⎪⎬⎪⎪⎫
如果顶点i和顶点j之间有边 那么a[i,j]和a[j,i]都为1。
有向图邻接矩阵存储方法
有向图的邻接矩阵存储的方法和无向图类似,只不过,有向图分为入度和出度,当顶点i指向顶点j,则a[i,j]=1,反之则a[j,i]=1。
如下图所示按照顺时针分别为1,2,3,4四个顶点。
此时的有向图的邻接矩阵表示为:
x
=
{
0
1
0
1
0
0
1
0
0
1
0
0
0
0
0
1
}
x= \left\{ \begin{matrix} 0&1&0&1\\ 0&0&1&0\\ 0&1&0&0\\ 0&0&0&1\\ \end{matrix} \right\}
x=⎩⎪⎪⎨⎪⎪⎧0000101001001001⎭⎪⎪⎬⎪⎪⎫
带权图的邻接矩阵存储方式
我就直接上图和矩阵了不多做解释了。
x
=
{
0
8
0
0
8
0
5
0
0
5
0
3
0
0
3
0
}
x= \left\{ \begin{matrix} 0&8&0&0\\ 8&0&5&0\\ 0&5&0&3\\ 0&0&3&0\\ \end{matrix} \right\}
x=⎩⎪⎪⎨⎪⎪⎧0800805005030030⎭⎪⎪⎬⎪⎪⎫
邻接矩阵这种存储方式比较浪费内存,对于无向图来说a[i,j]=1,那么a[j,i]也是等于1,其实只需要标记一个就可以了,这样就白白的浪费了一般的存储空间。如果我们存储的是稀疏图(顶点很多但是每个顶点的边不是很多的图),比如说qq和微信的好友,qq和微信的共同好友都是上亿的但是每个人的好友最多也就是几百个。如果在用邻接矩阵存储的话,绝大多部分的内存都被浪费了。
邻接矩阵的存储高效好计算,但是占据的内存比较多,如果是稀疏图这种数据结构,用邻接矩阵的方法存储就不是太划算了。
b.邻接表存储方法
邻接表的存储方式。类似于用散列表存储,就是每个顶点上边挂着一个链表,链表里边存储的就是当前顶点,指向的顶点的值。
如下图所示:(引用自极客时间数据结构与算法专栏图片)