矩阵的特殊存储结构与压缩策略
矩阵是线性代数的核心数据结构,在计算机中通常以二维数组存储。但对于特殊矩阵(如对称矩阵、三对角矩阵)和稀疏矩阵,直接使用二维数组会导致大量空间浪费。因此,针对这些矩阵的特性,需要设计专门的压缩存储方案。
对称矩阵的压缩存储
对称矩阵的核心特性是 A[i][j] = A[j][i]
(元素关于主对角线对称),因此只需存储主对角线及一侧的元素(通常选择下三角区 + 主对角线),即可完整表示矩阵,空间复杂度从 O(n²)
降至 O(n²/2)
。
存储规则
设矩阵为 n×n
阶对称矩阵,仅存储满足 i ≥ j
(下三角区及主对角线)的元素:
- 按行优先顺序存储,将二维坐标
(i, j)
映射到一维数组sa[k]
中。 - 映射公式:
对于i ≥ j
,k = i×(i+1)/2 + j
(推导:第0
行存1
个元素,第1
行存2
个元素,…,第i
行存i+1
个元素,前i
行共i×(i+1)/2
个元素,加上第i
行的第j
个元素,总索引为i×(i+1)/2 + j
)。
元素访问
- 当
i ≥ j
时,直接通过k = i×(i+1)/2 + j
访问sa[k]
。 - 当
i < j
时,利用对称性A[i][j] = A[j][i]
,通过k = j×(j+1)/2 + i
访问。
示例:3×3 对称矩阵
1 | 原矩阵 压缩存储(sa[6]) |
访问 A[0][1]
时,因 0 < 1
,等价于 A[1][0]
,对应 sa[1] = 4
。
三对角矩阵的压缩存储
三对角矩阵(带状矩阵)的特性是:仅主对角线、主对角线上下邻接的对角线(次对角线)上有非零元素,其余位置均为 0。对于 n×n
阶三对角矩阵,非零元素集中在 |i-j| ≤ 1
的区域,总非零元素约为 3n-2
个,空间复杂度可从 O(n²)
降至 O(n)
。
存储规则
按行优先顺序存储三条对角线上的元素,将二维坐标 (i, j)
映射到一维数组 sa[k]
中:
- 映射公式:k = 2i + j(i从 0 开始,j满足i-1 ≤ j ≤ i+1且0 ≤ j < n)。
- 第
0
行有 2 个元素(j=0,1
)。 - 第
1
至n-2
行每行有 3 个元素(j=i-1,i,i+1
)。 - 第
n-1
行有 2 个元素(j=n-2,n-1
)。
- 第
元素访问
- 对于非零元素(
|i-j| ≤ 1
),直接通过k = 2i + j
访问。 - 对于零元素(
|i-j| > 1
),无需存储,直接返回 0。
示例:5×5 三对角矩阵
1 | 原矩阵(非零元素) 压缩存储(sa[13]) |
稀疏矩阵的压缩存储
稀疏矩阵的定义是:非零元素数量远小于矩阵总元素数量(通常非零元素占比 < 5%)。直接存储会浪费大量空间,需通过仅记录非零元素实现压缩。常见方案有三元组表和十字链表。
三元组表(顺序存储)
核心思想:用一个一维数组存储所有非零元素,每个元素记录其
(行号, 列号, 值)
三元组,同时记录矩阵的总行数、总列数和非零元素总数。结构定义:
1
2
3
4
5
6
7
8
9typedef struct {
int i, j; // 非零元素的行、列下标
ElemType val; // 非零元素值
} Triple;
typedef struct {
Triple data[MAXSIZE]; // 三元组数组
int rows, cols, cnt; // 矩阵行数、列数、非零元素数
} TSMatrix; // 三元组顺序表优缺点:
- 优点:结构简单,节省空间。
- 缺点:不便于动态插入 / 删除非零元素,适合静态稀疏矩阵。
十字链表(链式存储)
核心思想:为每个非零元素创建一个节点,同时按行和列维护链表(每行、每列的非零元素构成一条链表),便于动态操作。
节点结构:
1
2
3
4
5
6
7
8
9
10typedef struct OLNode {
int i, j; // 行、列下标
ElemType val; // 元素值
struct OLNode *right, *down; // 向右(同列下一个)、向下(同行下一个)指针
} OLNode, *Olink;
typedef struct {
Olink *row_head, *col_head; // 行、列链表头指针数组
int rows, cols, cnt; // 矩阵行数、列数、非零元素数
} CrossList; // 十字链表优缺点:
- 优点:支持高效的插入 / 删除操作,适合动态稀疏矩阵(如矩阵运算过程中)。
- 缺点:结构复杂,实现难度较高。
总结
矩阵类型 | 存储策略 | 空间复杂度 | 适用场景 |
---|---|---|---|
对称矩阵 | 存储下三角区 + 主对角线 | O(n²)→O(n²/2) | 元素关于主对角线对称(如协方差矩阵) |
三对角矩阵 | 存储三条对角线元素 | O(n²)→O(n) | 带状矩阵(如微分方程离散化结果) |
稀疏矩阵 | 三元组表(静态)、十字链表(动态) | O (n²)→O (k)(k 为非零元素数) | 非零元素极少的大型矩阵(如神经网络权重矩阵) |
选择压缩存储方案时,需权衡空间效率与操作复杂度:静态场景优先选顺序存储(如三元组表),动态场景需选链式存储(如十字链表)
v1.3.10