数据结构与算法 —— 矩阵的压缩存储

【概述】

矩阵的压缩存储主要是针对于特殊矩阵和稀疏矩阵:

  • 特殊矩阵:矩阵中很多值相同的元素且分布有一定规律。
  • 稀疏矩阵:矩阵中有很多零元素。

压缩存储的基本思想是:

  • 为多个值相同的元素只分配一个存储空间。
  • 对零元素不分配存储空间。 

【压缩矩阵】

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;};
};

发布了1871 篇原创文章 · 获赞 702 · 访问量 194万+

猜你喜欢

转载自blog.csdn.net/u011815404/article/details/89326064
今日推荐