zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

7.3 图的存储方式

存储 方式 7.3
2023-09-11 14:20:29 时间

  这里说的图的存储方式,是说边的存储方式。目前主流的有两种存储方式,一种是邻接矩阵Adjacency Matrix,一种是邻接数组Adjacency List。这两种存储方式有各自的场景。邻接矩阵用于图的边特别多的情况,接近完全图。而邻接数组的思想来源于稀疏矩阵的存储优化。稀疏矩阵,指的是0特别多的矩阵,这种矩阵如果用二维数组来存储,就造成了内存的极大浪费了。以这个图为例子:
在这里插入图片描述
  首先以邻接矩阵来存储,将图中每个节点都进行编号。以1234为0,按顺时针方向分别为1、2、3直到11。看看邻接矩阵是什么样子:
0 1 2 3 4 5 6 7 8 9 10 11 0 0 1 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 2 0 1 0 1 0 0 0 0 0 0 0 0 3 0 0 1 0 1 0 0 0 0 0 0 0 4 0 0 0 1 0 1 0 0 0 0 0 0 5 0 0 0 0 1 0 1 0 0 0 0 0 6 0 0 0 0 0 1 0 1 0 0 0 0 7 0 0 0 0 0 0 1 0 1 0 0 0 8 0 0 0 0 0 0 0 1 0 1 0 0 9 0 0 0 0 0 0 0 0 1 0 1 0 10 0 0 0 0 0 0 0 0 0 1 0 1 11 1 0 0 0 0 0 0 0 0 0 1 0 \begin{array} {c|c} & 0 & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11\\ 0 & 0 &1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ 1 & 1 & 0 & 1& 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 2 & 0 & 1& 0 &1 & 0& 0& 0& 0& 0& 0& 0& 0\\ 3 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ 4& 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\ 5& 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\ 6 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0\\ 7& 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0\\ 8& 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0\\ 9 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0\\ 10 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1\\ 11 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \end{array} 0123456789101100100000000011101000000000201010000000030010100000004000101000000500001010000060000010100007000000101000800000001010090000000010101000000000010111100000000010
  看上去很美,但是实际上很浪费内存。如果实用邻接数组去存储呢?那么就是以下形式:
i n d e x f r o m t o 0 0 1 1 1 0 2 1 2 3 2 1 4 2 3 5 3 2 6 3 4 7 4 3 8 4 5 9 5 4 10 5 6 11 6 5 12 6 7 13 7 6 14 7 8 15 8 7 16 8 9 17 9 8 18 9 10 19 10 9 20 10 11 21 11 10 22 11 0 23 0 11 \begin{array} {|c|c|c|} index & from & to \\ 0 & 0 & 1 \\ \hline 1 & 1 & 0 \\ \hline 2 & 1 & 2 \\ \hline 3 & 2 &1 \\ \hline 4 & 2 & 3 \\ \hline 5 & 3 & 2 \\ \hline 6 & 3 & 4 \\ \hline 7 & 4 & 3 \\ \hline 8 & 4 & 5 \\ \hline 9 & 5 & 4 \\ \hline 10 & 5 & 6 \\ \hline 11 & 6 & 5\\ \hline 12 & 6 & 7 \\ \hline 13 & 7 & 6 \\ \hline 14 & 7 & 8 \\ \hline 15 & 8 & 7 \\ \hline 16 & 8 & 9 \\ \hline 17 & 9 & 8 \\ \hline 18 & 9 & 10 \\ \hline 19 & 10 & 9 \\ \hline 20 & 10 & 11 &\\ \hline 21 & 11 & 10 &\\ \hline 22 & 11 & 0 &\\ \hline 23 & 0 & 11 &\\ \hline \end{array} index01234567891011121314151617181920212223from0112233445566778899101011110to1021324354657687981091110011
  但是邻接数组也有替代的方案,就是在图的节点类中加上一个邻接数组属性。这种方式也是比较节省内存的。因为邻接数组的存储方式中,边这个类里有from和to两个属性,所以在密集矩阵的场景下,比如完全图中,多出来的两个属性反而会使内存占用更大,这个时候邻接矩阵是更合适的方案。