Special Matrix Compressed Storage
普通矩阵
普通矩阵通常直接用二维数组存储。若矩阵为 m 行 n 列,需要存储 m * n 个元素。
描述矩阵元素时常写作 $a_{i,j}$,行列号通常从 1 开始;描述数组位置时通常从 0 开始。
特殊矩阵的压缩存储
特殊矩阵仍然存入一维连续内存。只是特殊矩阵中大量元素可由少量信息推出。因此可以压缩存储只保存必要元素,再通过下标映射恢复矩阵位置。
这里规定$a_{k}$是物理存储方式中的第$k$个元素,且$1\leqslant k\leqslant total$
$n$行$n$列对称矩阵
对称矩阵满足:
$$
a_{i,j} = a_{j,i}
$$
只需存储主对角线和一个三角区,共$\frac{n(n+1)}{2}$个元素。
若按行优先存储下三角区和主对角线,且矩阵下标从 1 开始、一维数组 B 下标从 0 开始:
$$
k = \frac{i(i-1)}{2} + j - 1,\quad i \ge j
$$
若访问上三角区元素 $a_{i,j}$,利用对称性转成 $a_{j,i}$:
$$
k = \frac{j(j-1)}{2} + i - 1,\quad i < j
$$
$n$行$n$列三角矩阵
下三角矩阵:主对角线和下三角区元素任意,上三角区元素都相同,通常记为常量 c。压缩时存储下三角区和主对角线,再额外存储一个 c。
按行优先存储下三角矩阵:
$$
k =
\begin{cases}
\frac{i(i-1)}{2}+j-1, & i \ge j \
\frac{n(n+1)}{2}, & i < j
\end{cases}
$$
上三角矩阵:主对角线和上三角区元素任意,下三角区元素都相同。按行优先存储上三角矩阵:
$$
k =
\begin{cases}
\frac{(i-1)(2n-i+2)}{2} + (j-i), & i \le j \
\frac{n(n+1)}{2}, & i > j
\end{cases}
$$
三角矩阵的一维数组长度通常是:
$$
\frac{n(n+1)}{2}+1
$$
最后一个位置存放重复常量。
$n$行$n$列三对角矩阵
三对角矩阵又称带状矩阵,满足:
$$
|i-j| > 1 \Rightarrow a_{i,j}=0
$$
只存储主对角线、上方一条对角线、下方一条对角线,共 3n - 2 个元素。
按行优先存储,矩阵下标从 1 开始、一维数组下标从 0 开始:
$$
k = 2i + j - 3,\quad |i-j| \le 1
$$
由 k 反求行列时,先确定第 k+1 个存储元素落在哪一行:
$$
i = \left\lfloor \frac{k+1}{3} \right\rfloor + 1
$$
再由映射式得到:
$$
j = k - 2i + 3
$$
稀疏矩阵
稀疏矩阵的非零元素远少于矩阵元素总数,且不一定是方阵。常见压缩方式:
- 三元组顺序表:每个非零元素保存
<row, col, value>。 - 十字链表:每个非零结点保存行号、列号、值、同行下一个结点指针、同列下一个结点指针。
三元组适合顺序扫描和转置等操作;十字链表适合按行、按列都需要快速链接非零元素的场景。
易错点
- 公式中的
i、j是否从1开始,要和题目一致。 - 对称矩阵不需要额外存储另一半;三角矩阵需要额外存储重复常量。
- 三对角矩阵不是三角矩阵,只存储三条对角线。
- 稀疏矩阵压缩的是非零元素,不是按对角线或三角区压缩。