特殊矩阵的压缩存储
矩阵在很多学科领域都有非常重要的应用。不过,在数据结构中矩阵最需要考虑的是:如何用最小的内存空间来存储同样的一组数据。所以,我们不研究矩阵性质及其运算等,而是侧重于解决如何将矩阵更加有效的存储在内存中的问题,并能方便的提取矩阵中的元素
1 数组的定义
数组是一种基本上计算机语言都会提供的数组数据类型,这是由n个相同类型的数据元素构成的有限序列。
数组和线性表的关系:数组是线性表的推广。一维数组可视为一个线性表,二维数组也可以视为一种线性表,只不过该线性表的元素的数据类型也是一种长度限定了的线性表,以此类推。一旦数组被定义,维数和维界都不再改变。
2 数组的存储结构
一个数组的所有元素会在内存中占用一段连续的空间
对于多维数组,有两种映射放射:按行优先和按列优先。
例如:
A
2
×
3
A_{2\times3}
A2×3,在内存中的存储形式如下
按照行优先方式:
按照列优先方式:
3 特殊矩阵的压缩存储
压缩存储:指为多个值相同的元素只分配一个存储空间空间,对零元素不分配存储空间。其目的是节省存储空间。
特殊矩阵:指具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分布有一定规律性的矩阵。常见的特殊矩阵有对称矩阵、上(下)三角矩阵、对角矩阵等。
特殊矩阵的压缩存储方法:找出特殊矩阵中值相同的矩阵元素的分布规律,把那些呈现规律性分布的,值相同的多个矩阵元素压缩存储到一个存储空间。
3.1 对称矩阵
若对一个n阶方阵A[1…n][1…n]中的任意一个元素
a
i
,
j
a_{i,j}
ai,j都有
a
i
,
j
=
a
j
,
i
(
1
⩽
i
,
j
⩽
n
)
a_{i,j}=a_{j,i}(1\leqslant i,j\leqslant n)
ai,j=aj,i(1⩽i,j⩽n)
对于n阶对称矩阵,上三角区的所有元素和下三角区的对应元素相同,若扔采用二维数组存放,则会浪费几乎一半的空间,为此将对称矩阵A[1…n][1…n]存放在一维数组B[n(n+1)/2]中,即元素
a
i
,
j
a_{i,j}
ai,j存放
b
k
b_k
bk中,只存放下三角部分(含主对角线)的元素。
假设有一个数组B存放上面的对称矩阵,按行存放下三角区,元素
a
i
,
j
a_{i,j}
ai,j在数组B(数组从0开始)中对应的下标是:
k
=
{
i
(
i
−
1
)
2
+
j
−
1
,
i
⩾
j
(
下
三
角
区
和
主
对
角
线
元
素
)
j
(
j
−
1
)
2
+
i
−
1
,
i
<
j
(
上
三
角
区
元
素
)
k= \begin{cases} \dfrac{i(i-1)}{2}+j-1 ,i\geqslant j(下三角区和主对角线元素)\\ \dfrac{j(j-1)}{2}+i-1 ,i<j(上三角区元素) \end{cases}
k=⎩⎪⎨⎪⎧2i(i−1)+j−1,i⩾j(下三角区和主对角线元素)2j(j−1)+i−1,i<j(上三角区元素)
3.2 三角矩阵
下三角矩阵中,上三角区的所有元素均为同一常量。
存储思想为,用数组存储完下三角区和主对角线的元素之后,直到这里都是和对称矩阵的思想一致的,不同点在于下三角矩阵还要紧接着存储对角线上方的常量,存储一次。将下三角矩阵A[1…n][1…n]存放在数组B[n(n+1)/2+1]中。存储形势如下图所示:
元素
a
i
,
j
a_{i,j}
ai,j和数组下标之间的对应关系为:
k
=
{
i
(
i
−
1
)
2
+
j
−
1
,
i
⩾
j
(
下
三
角
区
和
主
对
角
线
元
素
)
n
(
n
−
1
)
2
,
i
<
j
(
上
三
角
区
元
素
)
k= \begin{cases} \dfrac{i(i-1)}{2}+j-1 ,i\geqslant j(下三角区和主对角线元素)\\ \dfrac{n(n-1)}{2} ,i<j(上三角区元素) \end{cases}
k=⎩⎪⎨⎪⎧2i(i−1)+j−1,i⩾j(下三角区和主对角线元素)2n(n−1),i<j(上三角区元素)
上三角矩阵,下三角区的所有元素均为同一常量。
和下三角区的存储思想一样,只存主对角线、上三角区上的元素和下三角区的常量一次。将上三角矩阵A[1…n][1…n]存放在数组B[n(n+1)/2+1]中。存储形势如下图所示:
元素
a
i
,
j
a_{i,j}
ai,j和数组下标之间的对应关系为:
k
=
{
(
i
−
1
)
(
2
n
−
i
+
2
)
2
+
(
j
−
i
)
,
i
⩽
j
(
上
三
角
区
和
主
对
角
线
元
素
)
n
(
n
−
1
)
2
,
i
>
j
(
下
三
角
区
元
素
)
k= \begin{cases} \dfrac{(i-1)(2n-i+2)}{2}+(j-i) ,i\leqslant j(上三角区和主对角线元素)\\ \dfrac{n(n-1)}{2} ,i>j(下三角区元素) \end{cases}
k=⎩⎪⎨⎪⎧2(i−1)(2n−i+2)+(j−i),i⩽j(上三角区和主对角线元素)2n(n−1),i>j(下三角区元素)
以上的解释数组下标都是从0开始的。
3.3 三对角矩阵
对角矩阵也称为带状矩阵。对于n阶方阵A中的任一元素
a
i
,
j
a_{i,j}
ai,j,当
∣
i
−
j
∣
>
1
\left\vert i-j \right\vert>1
∣i−j∣>1时,有
a
i
,
j
=
0
(
1
⩽
n
)
a_{i,j}=0(1\leqslant n)
ai,j=0(1⩽n),则称为三对角矩阵。
在三对角矩阵中,所有非零元素都集中在以主对角线为中心的三条对角线区域,其他区域元素都为零。
存储思想:将三条对角线上的元素按行优先方式存放在一维数组中。
元素
a
i
,
j
(
1
⩽
i
,
j
⩽
j
,
∣
i
−
j
∣
⩽
1
)
a_{i,j}(1\leqslant i ,j\leqslant j,\left\vert i-j \right\vert \leqslant 1)
ai,j(1⩽i,j⩽j,∣i−j∣⩽1)和数组下标之间的对应关系为:
k
=
2
i
+
j
−
3
k=2i+j-3
k=2i+j−3
3.4 稀疏矩阵
矩阵中非零元素的个数,相比矩阵元素的个数来说非常少。这样的矩阵称为稀疏矩阵。例如
存储思想:仅存储非零元素,不仅要存储非零元素的值,还要存储它所在的行和列。将非零元素和它的行和列构成一个三元组(行标,列标,值)。值得注意的是稀疏矩阵压缩存储后便失去了随机存取的特性。
这个三元组可以采用数组存储,也可以采用十字链表法存储。