特殊矩阵的压缩存储

1860 字
9 分钟
特殊矩阵的压缩存储
Warning

含AI生成内容

特殊矩阵的压缩存储#

为什么要压缩#

对于 n×nn \times n 的矩阵,朴素存储要 n2n^2 个单元。当矩阵具有某种规律性时,朴素存储是浪费的。压缩存储的目标:只保留有用信息,并能 O(1)O(1) 反算出原矩阵任一位置的值

四类特殊矩阵的压缩:

矩阵规律压缩思路
对称矩阵mi,j=mj,im_{i,j} = m_{j,i}只存一半三角
三角矩阵一半三角全是常数 cc存非零三角 + 1 个 cc
三对角矩阵非零只在 $i-j
稀疏矩阵非零元素稀疏分布、无规律存 (行, 列, 值) 三元组

前三类是规律性压缩,第四类是显式存位置


对称矩阵#

定义#

n×nn \times n 矩阵 MM 满足 mi,j=mj,im_{i,j} = m_{j,i}(对所有 1i,jn1 \leq i,j \leq n)。只存上三角下三角,共 n(n+1)2\frac{n(n+1)}{2} 个元素。

上三角 · 行优先公式(1-based)#

ii 行:mi,i,mi,i+1,,mi,nm_{i,i}, m_{i,i+1}, \ldots, m_{i,n},共 ni+1n-i+1 个。

idx(mi,j)=(i1)(2ni+2)2+(ji)(ji)\boxed{\text{idx}(m_{i,j}) = \frac{(i-1)(2n-i+2)}{2} + (j-i)} \quad (j \geq i)

上三角 · 列优先公式(1-based)#

jj 列:m1,j,m2,j,,mj,jm_{1,j}, m_{2,j}, \ldots, m_{j,j},共 jj 个。

idx(mi,j)=j(j1)2+(i1)(ji)\boxed{\text{idx}(m_{i,j}) = \frac{j(j-1)}{2} + (i-1)} \quad (j \geq i)

下三角元素查询模板(⭐高频陷阱)#

当题目”只存上三角”且要查的元素在下三角时:

  1. mi,j=mj,im_{i,j} = m_{j,i} 交换下标
  2. 重新核对交换后是否进入上三角(jij \geq i
  3. 代入公式

⚠️ 易错:漏掉第一步是 2020-01 选错最常见的原因。

真题精讲:2018-03(上三角行优先)#

12×1212 \times 12 对称矩阵 MM,上三角按行优先存入一维数组 NN(C 语言,0-based),求 m6,6m_{6,6} 的下标。

m6,6m_{6,6} 已在 jij \geq i 的上三角区域。代入 n=12,i=6,j=6n=12, i=6, j=6

idx=5×(246+2)2+(66)=5×202+0=50\text{idx} = \frac{5 \times (24 - 6 + 2)}{2} + (6-6) = \frac{5 \times 20}{2} + 0 = 50

答案 50(手算验证:前 5 行共 12+11+10+9+8=5012+11+10+9+8=50 个元素,m6,6m_{6,6} 是第 6 行第一个)。

真题精讲:2020-01(上三角列优先 + 对称性)#

10×1010 \times 10 对称矩阵 MM,上三角按列优先存入 NN,求 m7,2m_{7,2} 的下标。

第一步m7,2m_{7,2} 在下三角,用对称性:m7,2=m2,7m_{7,2} = m_{2,7},查 i=2,j=7i=2, j=7

第二步:代入列优先公式: idx=7×62+(21)=21+1=22\text{idx} = \frac{7 \times 6}{2} + (2-1) = 21 + 1 = 22

答案 22

行优先 vs 列优先公式对比#

行优先列优先
kk 行/列长度nk+1n-k+1(递减)kk(递增)
“前部”求和(i1)(2ni+2)2\frac{(i-1)(2n-i+2)}{2}j(j1)2\frac{j(j-1)}{2}
行/列内偏移jij-ii1i-1

三角矩阵#

定义#

  • 上三角矩阵i>ji > j(下三角部分)的元素都等于同一常数 cc
  • 下三角矩阵i<ji < j(上三角部分)的元素都等于同一常数 cc

压缩策略#

存非常数部分的 n(n+1)2\frac{n(n+1)}{2} 个元素 + 1 个常数 cc,共 n(n+1)2+1\frac{n(n+1)}{2} + 1 个。

  • 非常数部分的下标公式与对称矩阵的对应三角完全相同
  • 常数 cc 单独存在末尾位置 N[n(n+1)2]N[\frac{n(n+1)}{2}]

三角矩阵 vs 对称矩阵(⭐辨析)#

对称矩阵三角矩阵
另一半的内容与存储的一半相同(重复)全是常数 cc(不同)
压缩后大小n(n+1)2\frac{n(n+1)}{2}n(n+1)2+1\frac{n(n+1)}{2} + 1
下标公式相同相同(非常数部分)

三对角矩阵#

定义#

只有 ij1|i-j| \leq 1 的元素非零(主对角线 + 上下副对角线):

n=5 时的非零分布:
* *
* * *
* * *
* * *
* *

每行非零元素数#

  • 第 1 行:2 个 ⚠️
  • 2n12 \sim n-1 行:3 个
  • nn 行:2 个 ⚠️

总非零数:2+3(n2)+2=3n22 + 3(n-2) + 2 = 3n - 2

行优先下标公式(1-based)#

中间行(2in12 \leq i \leq n-1):

idx(mi,j)=2i+j3(ij1)\boxed{\text{idx}(m_{i,j}) = 2i + j - 3} \quad (|i-j| \leq 1)

手算验证m30,30m_{30,30} 之前有 2+3×28=862 + 3 \times 28 = 86 个元素(N[0]N[0]N[85]N[85])。第 30 行的 m30,29m_{30,29}m30,30m_{30,30}m30,31m_{30,31} 依次占 N[86]N[86]N[87]N[87]N[88]N[88]m30,30m_{30,30}N[87]N[87] → 代入公式:2×30+303=872 \times 30 + 30 - 3 = 87

三个高频坑(⭐)#

  1. 第 1 行只有 2 个元素——全部按 3 个算前缀和会错
  2. i=ji=j(主对角线)vs i=j1i=j-1(上副对角线)混淆——m30,30m_{30,30} 在第 30 行的中间不是第一个
  3. 公式 2i+j32i+j-3 只对中间行成立——i=1i=1i=ni=n 时单独处理

真题精讲:2016-04#

100 阶三对角矩阵 MM,按行优先存入下标从 0 的一维数组 NN。求 m30,30m_{30,30} 的下标。

代入 i=j=30i=j=30(属于 2i992 \leq i \leq 99 的常规行): idx=2×30+303=87\text{idx} = 2 \times 30 + 30 - 3 = 87

答案 87


稀疏矩阵#

定义#

非零元素个数 tt 远小于矩阵总元素数 m×nm \times n,且分布无规律。

三元组表#

对每个非零元素存一个三元组 (i,j,value)(i, j, value)

typedef struct {
int rows; // 原矩阵的行数
int cols; // 原矩阵的列数
int nums; // 非零元素个数
Triple data[N]; // 三元组数组
} TSMatrix;

除三元组本身外,还需存储原矩阵的行数和列数(不是非零行列数)。仅存非零行列数会丢失零元素的行/列信息,无法还原矩阵形状。

真题精讲:2023-03#

采用三元组表存储稀疏矩阵 M,除三元组外还需保存的是? I. M 的行数 II. M 中包含非零元素的行数 III. M 的列数 IV. M 中包含非零元素的列数

正确答案:I 和 III(原矩阵的行数和列数)。

反例:5×55 \times 5 矩阵只有 m1,1=1m_{1,1}=1,三元组为 {(1,1,1)}\{(1,1,1)\}。非零行数 II=1,非零列数 IV=1。如果只存 II+IV,重建出来是 1×11 \times 1 矩阵,原矩阵的 4 行 4 列零元素信息全部丢失。

十字链表#

适合频繁修改的稀疏矩阵。每个非零元素是一个节点,同时挂在所在行链表列链表上:

typedef struct OLNode {
int row, col;
ElemType value;
struct OLNode *right; // 同一行内下一个非零元素
struct OLNode *down; // 同一列内下一个非零元素
} OLNode;

优势:插入/删除 O(行长+列长)O(\text{行长}+\text{列长}),不需要移动其它元素。

三元组 vs 十字链表#

三元组表十字链表
存储开销小(3 个值)大(多 2 个指针)
插入/删除慢(数组移位)快(链表操作)
适用场景静态矩阵频繁修改

邻接矩阵不是稀疏矩阵的压缩结构(⭐辨析)#

邻接矩阵的”矩阵”二字容易误判为”与稀疏矩阵相关”。它就是一个普通的 n×nn \times n 二维数组,完全不压缩,0 元素照常占内存。稀疏图的邻接矩阵用三元组或十字链表压缩才高效。


四类矩阵对比速查#

矩阵非零分布压缩后大小关键公式(0-based 行优先)
对称矩阵(上三角)jij \geq in(n+1)2\frac{n(n+1)}{2}(i1)(2ni+2)2+(ji)\frac{(i-1)(2n-i+2)}{2} + (j-i)
对称矩阵(上三角列优先)jij \geq in(n+1)2\frac{n(n+1)}{2}j(j1)2+(i1)\frac{j(j-1)}{2} + (i-1)
三角矩阵一半 + 1 个常数n(n+1)2+1\frac{n(n+1)}{2}+1同对称矩阵对应三角
三对角矩阵ij1\|i-j\| \leq 13n23n-22i+j32i+j-3(中间行)
稀疏矩阵(三元组)任意稀疏3t+33t+3显式存 (i,j,v)(i,j,v)
稀疏矩阵(十字链表)任意稀疏5t+m+n\approx 5t+m+n链表节点

考研高频考点#

  • ⭐ 对称矩阵压缩下标公式(选择题必考)
  • ⭐ 下三角元素用对称性转换后查上三角公式(2020-01 陷阱)
  • ⭐ 三对角矩阵下标公式 2i+j32i+j-3(2016-04)
  • ⭐ 三对角矩阵第 1 行只有 2 个元素的边界处理
  • ⭐ 稀疏矩阵三元组需存原矩阵行数和列数(2023-03)
  • 三角矩阵 vs 对称矩阵的概念辨析
  • 三元组 vs 十字链表的适用场景选择
  • 邻接矩阵不是稀疏矩阵的压缩结构(2017-03)

关联页面#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

特殊矩阵的压缩存储
https://lingluoa.icu/posts/matrix-compression/
作者
lingluoa
发布于
2026-07-06
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
lingluoa
Hello, I'm lingluoa.
公告
欢迎来到我的博客!不定期更新中。
文章目录
标签
站点统计
文章
53
分类
9
标签
75
总字数
175,771
运行时长
0
最后活动
0 天前
站点信息
构建平台
ESA Pages
博客版本
Firefly v6.15.6
文章许可
CC BY-NC-SA 4.0