矩阵的常规存储与压缩存储
矩阵: 一个由
m
∗
n
m*n
m∗n个元素排成的m行n列的表。
[
a
11
a
12
⋯
a
1
n
a
21
a
22
⋯
a
2
n
⋯
⋯
⋯
⋯
a
m
1
a
m
2
⋯
a
m
n
]
\left[ {\begin{array}{} {{a_{11}}}&{{a_{12}}}& \cdots &{{a_{1n}}}\\ {{a_{21}}}&{{a_{22}}}& \cdots &{{a_{2n}}}\\ \cdots & \cdots & \cdots & \cdots \\ {{a_{m1}}}&{{a_{m2}}}& \cdots &{{a_{mn}}} \end{array}} \right]
⎣⎢⎢⎡a11a21⋯am1a12a22⋯am2⋯⋯⋯⋯a1na2n⋯amn⎦⎥⎥⎤
矩阵的常规存储: 用一个二维数组来描述矩阵。
矩阵的常规存储的特点:
- 优点:可以对其元素进行随机存取,矩阵运算非常简单,存储密度为1.
- 缺点:当矩阵中有很多值相同的元素且呈现某种规律分布时;或者矩阵中零元素很多时,用常规存储就很浪费存储空间。
针对矩阵的常规存储的缺点,这里对于某些特殊矩阵,可以使用压缩存储的方法。
矩阵的压缩存储: 为多个相同的非零元素只分配一个存储空间,同时对零元素不分配空间。
只有一些特殊的矩阵可以用压缩存储,这些矩阵有:对称矩阵,对角矩阵,三角矩阵,稀疏矩阵等。
对称矩阵的压缩存储
对称矩阵的特点:在
n
∗
n
n*n
n∗n的矩阵a中,满足以下性质:
a
i
j
=
a
j
i
(
1
≤
i
,
j
≤
n
)
a_{ij}=a_{ji}(1\le i,j\le n)
aij=aji(1≤i,j≤n)
例如,下面的就是对称矩阵,
[
1
5
1
3
7
5
0
8
0
0
1
8
9
2
6
3
0
2
5
1
7
0
6
1
3
]
\left[ {\begin{array}{} 1&5&1&3&7\\ 5&0&8&0&0\\ 1&8&9&2&6\\ 3&0&2&5&1\\ 7&0&6&1&3 \end{array}} \right]
⎣⎢⎢⎢⎢⎡1513750800189263025170613⎦⎥⎥⎥⎥⎤
存储方法: 只存储下三角(或上三角)的数据元素(包括主对角线),共占用 n ( n + 1 ) / 2 n(n+1)/2 n(n+1)/2个元素空间。
可以以行序为主序将元素存放在一个一维数组sa[
n
(
n
+
1
)
/
2
n(n+1)/2
n(n+1)/2]中。
对称矩阵中的元素
a
i
j
a_{ij}
aij对应于上图一维数组里的第k个元素,那么k与i,j有什么映射关系?
k
=
(
i
−
1
)
i
/
2
+
j
−
1
k=(i-1)i/2+j-1
k=(i−1)i/2+j−1
三角矩阵的压缩存储
三角矩阵的特点:对角线以上(或以下)的数据元素(不包括对角线)全部为常数c。
存储方法: 重复元素c共享一个元素的存储空间,共占用
n
(
n
+
1
)
/
2
+
1
n(n+1)/2+1
n(n+1)/2+1个存储空间。
计算公式为:
- 上三角矩阵
k = { ( i − 1 ) ( 2 n − i + 2 ) 2 + j − i + 1            i ≤ j n ( n + 1 ) 2 + 1                                                    i > j k = \left\{ {\begin{array}{l} {\frac{{(i - 1)(2n - i + 2)}}{2} + j - i + 1\;\;\;\;\;i \le j}\\ {\frac{{n(n + 1)}}{2} + 1\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;i > j} \end{array}} \right. k={2(i−1)(2n−i+2)+j−i+1i≤j2n(n+1)+1i>j - 下三角矩阵
k = { i ( i − 1 ) 2 + j            i ≥ j n ( n + 1 ) 2 + 1          i < j k = \left\{ {\begin{array}{l} {\frac{{i(i - 1)}}{2} + j\;\;\;\;\;i \ge j}\\ {\frac{{n(n + 1)}}{2} + 1\;\;\;\;i < j} \end{array}} \right. k={2i(i−1)+ji≥j2n(n+1)+1i<j
对角矩阵的压缩存储
对角矩阵的特点:在
n
∗
n
n*n
n∗n的方阵中,所有非零元素都集中在以主对角线为中心的带状区域中,区域外的值全部为0,这就是对角矩阵。
常见的有三对角矩阵,五对角矩阵,七对角矩阵等。
存储方法: 以对角线的顺序存储,例如,
如下图,本来需要36个存储空间,现在只需要30个存储空间。
稀疏矩阵的压缩存储
稀疏矩阵: 设在 m ∗ n m*n m∗n的矩阵中有t个非零元素,则当 δ = t m ∗ n ≤ 0.05 \delta = \frac{t}{{m*n}} \le 0.05 δ=m∗nt≤0.05时称为稀疏矩阵。
存储方法(两种):
- 三元组顺序表
只存储稀疏矩阵的非零元素,存储非零元素的行号,列号,以及云素值,如果第i行第j列的非零元素值为v,则其三元组为 ( i , j , v ) (i,j,v) (i,j,v),为了使描述更可靠,通常还要在三元组表的开头存放矩阵的总行数,总列数和非零元素的总个数。
例子如下,现有一个矩阵,
[
0
12
9
0
0
0
0
0
0
0
0
0
−
3
0
0
0
14
0
0
0
24
0
0
0
0
18
0
0
0
0
15
0
0
−
7
0
0
]
\left[ {\begin{array}{} 0&{12}&9&0&0&0\\ 0&0&0&0&0&0\\ { - 3}&0&0&0&{14}&0\\ 0&0&{24}&0&0&0\\ 0&{18}&0&0&0&0\\ {15}&0&0&{ - 7}&0&0 \end{array}} \right]
⎣⎢⎢⎢⎢⎢⎢⎡00−3001512000180900240000000−70014000000000⎦⎥⎥⎥⎥⎥⎥⎤
上述矩阵的三元组表为:
6 | 6 | 8 |
---|---|---|
1 | 2 | 12 |
1 | 3 | 9 |
3 | 1 | -3 |
3 | 5 | 14 |
4 | 3 | 24 |
5 | 2 | 18 |
6 | 1 | 15 |
6 | 4 | -7 |
该存储法的优点:非零元素在表中按行序有序存储,因此便于进行依行顺序处理的矩阵运算。
该存储法的缺点:不能随机存取。若按行号存取某一行中的非零元素,则需要从头开始查找。
- 十字链表
- 优点: 它能灵活地插入因运算而产生地新的非零元素,删除因运算而产生地新的零元素,实现矩阵的各种烦运算。
- 十字链表的表示: 在十字链表中,矩阵的每一个非零元素用一个结点表示,该结点除了(row,col,value)外,还有两个指针域,
- right域:用于链接同一行中下一个非零元素。
- down域:用于链接同一列中下一个非零元素。
其示意图如下:
例子如下,现有一矩阵M,
M
=
[
3
0
0
5
0
−
1
0
0
2
0
0
0
]
M=\left[ {\begin{array}{} 3&0&0&5\\ 0&{ - 1}&0&0\\ 2&0&0&0 \end{array}} \right]
M=⎣⎡3020−10000500⎦⎤
则其十字链表为: