【概述】
矩阵的压缩存储主要是针对于特殊矩阵和稀疏矩阵:
- 特殊矩阵:矩阵中很多值相同的元素且分布有一定规律。
- 稀疏矩阵:矩阵中有很多零元素。
压缩存储的基本思想是:
- 为多个值相同的元素只分配一个存储空间。
- 对零元素不分配存储空间。
【压缩矩阵】
1.对称矩阵
根据对称矩阵的特点:a[i][j]=a[j][i],那么可以只存储矩阵的下三角部分。
下三角矩阵中共有 n*(n+1)/2 个元素,可将这些元素按行存储到一个数组 SA[n*(n+1)/2] 中
那么对于对称矩阵中的对于第 i 行第 j 个元素其序号为 1+2+...+i-1+j,即:i*(i-1)/2+j
由于一维数组下标从 0 开始,那么对于其在一维数组中的下标 k=i*(i+1)/2+j-1
对于上三角中的元素 a[j][i],由于a[i][j]=a[j][i],则访问与其对应的下三角元素 a[i][j] 即可,即:k=j*(i-1)/2+i-1
2.三角矩阵
三角矩阵分为上三角矩阵与下三角矩阵:
- 上三角矩阵:主对角线以下全是常数 c
- 下三角矩阵:主对角线以上全是常数 c
1)下三角矩阵
下三角矩阵的存储与对称矩阵相似,不同之处仅在于除了存储下三角中的元素外,还要存储对角线上方的常数,由于常数相同,因此存储一个即可,这样共存储 n*(n+1)/2+1 个元素,可将这些元素按行存储到一个数组 SA[n*(n+1)/2+1] 中。
下三角矩阵中任一元素 a[i][j] 在 SA 数组中的下标 k 与 i、j 的对应关系为:
- i>=j:k=i*(i-1)/2+j-1
- i<j:k=n*(n+1)/2
2)上三角矩阵
上三角矩阵的存储与下三角矩阵类似。
上三角矩阵中任一元素 a[i][j] 在 SA 数组中的下标 k 与 i、j 的对应关系为:
- i<=j:k=(i-1)*(2n-i+2)/2+j-i
- i>j:k=n*(n+1)/2
3.对角矩阵
对角矩阵,即除主对角线和它的上下方若干条对角线的元素外,所有其他元素都为零。
其压缩存储的方式有两种:一维数组压缩、二维数组压缩
1)一维数组压缩
对于 w 对角矩阵,其第 i 行第 j 列的元素序号为前 i-1 行元素个数+第 i 行元素个数,即:w+3*(i-w)+(j-i+w) = 2i+j-w
由于一维数组下标从 0 开始,那么元素 a[i][j] 在数组中的下标 k=2i+j-w-1
2)二维数组压缩
如上图,对于对角矩阵,可将其转为二维数组存储。
对于一个 n*m 的 w 对角矩阵,可将其压缩到 m 行 w 列的二维数组中,a[i][j] 映射为 b[t][s],其映射关系为:
- t=i
- s=j-i+2
【稀疏矩阵】
1.三元组
将稀疏矩阵的非零元素对应的三元组所构成的集合,按行优先的顺序排列成线性表,则稀疏矩阵的压缩存储转化为三元组表的存储。
template<class T>
struct Element{
int row,col;
T item;
};
2.三元顺序表
采用顺序存储结构存储的三元组表即为三元顺序表,但要表示一个稀疏矩阵,还要在存储三元组表时存储矩阵的行数、列数、非零元素个数。
const int N=100;
template<class T>
struct sparseMatrix{
Element data[N];
int row,col,num;
};
3.十字链表
采用链式存储结构存储的三元组表即为十字链表,其具备链接存储的特点,其对矩阵运算操作较三元顺序表要方便许多。
十字链表存储稀疏矩阵的基本思想是:将每个非零元素对应的三元组存储为一个链表结点,结点由 5 个域组成,element 为数据域,存储非零元素对应的三元组,right、down 为指针域,分别指向同一行、同一列中的下一个三元组
template<class T>
class olNode{
public:
int row,col;
T element;
olNode<T>* right,*down;
public:
olNode(){right=NULL;down=NULL;};
};