多维数组之矩阵的压缩存储

来源:互联网 发布:c语言天津理工大学 编辑:程序博客网 时间:2024/05/01 01:28

一、对称矩阵的压缩存储

       对称矩阵的特点:在一个n阶方阵中,有aij=aji(0<=i,j<=n-1)。例如:

       

         对称矩阵关于主对角对称,因此只需要存储下三角的部分(包括主对角线)即可。这样,原来需要n*n个存储单元,现在只需要n*(n+1)/2个存储单元,节约了近一半的存储空间。

        由于下三角中共有n*(n+1)/2个元素,可以将这些元素按照行存储到一个数组A[n*(n+1)/2]中。这样,下三角中的元素aij存储到A[k]中,在数组A中的下标k与i和j的对应关系是:

k=i*(i+1)/2+j。例如:



symmetryArray.cpp

#include <iostream>using namespace std;void symmetryArray(int a[][5],int* b){int i=0;int j=0;for(i=0;i<5;i++){for(j=0;j<=i;j++){b[i*(i+1)/2+j]=a[i][j];}}}int main(){int a[5][5]={{3,6,4,7,8},{6,2,8,4,2},{4,8,1,6,9},{7,4,6,0,5},{8,2,9,5,7}};int b[15];symmetryArray(a,b);for(int i=0;i<15;i++){cout<<b[i]<<" ";}cout<<endl;}

测试结果:


        对于上三角中的元素aij(i<j),因为aij=aji,则访问和它对应的下三角中的元素aji即可,即k=j*(j+1)/2+i。



二、三角矩阵的压缩存储

        三角矩阵的特点:如下图所示,第一张图为下三角矩阵,主对角线以上的是常数c,第二张图是上三角矩阵,主对角线以下是常数c。

                      

             这里我们也只讨论下三角矩阵。下三角矩阵与对称矩阵类似,不同之处仅在于除了存储下三角中的元素以外,还要存储对角线以上的常数。因为是同一个常数,所以只存储一个就够了。这样需要存储n*(n+1)/2+1个元素,按照行优先存入数组A[n*(n+1)/2+1]中。下三角矩阵中任意一个元素aij在A中的下标k与i和j的对应关系是:如果i>=j,则k=i*(i+1)/2+j;如果i<j,则k=n*(n+1)/2。

      

triangleArray.cpp

#include <iostream>using namespace std;void triangleArray(int a[][5],int b[]){int i=0;int j=0;for(i=0;i<5;i++){for(j=0;j<5;j++){if(i>=j)b[i*(i+1)/2+j]=a[i][j];elseb[15]=a[i][j];}}}int main(){int a[5][5]={{3,0,0,0,0},{6,2,0,0,0},{4,8,1,0,0},{7,4,6,2,0},{8,2,9,5,7}};int b[16];triangleArray(a,b);for(int i=0;i<16;i++){cout<<b[i]<<" ";}cout<<endl;}

测试结果:




三、对角矩阵的压缩存储

        对角阵的特点:在对角阵中,所有 非零元素都集中在以主对角线为中心的带状区域,除了主对角线和它的上下方若干条对角线元素外,所有其他元素都是0。因此,对角矩阵也称为带状矩阵。如下图:

       

        将对角矩阵压缩存储到一维数组A中,按行存储其非零元素。对角矩阵中任意一个元素aij在A中的下标k与i和j的对应关系是:k=2+3*(i-1)+(j-i+1)=2i+j。

duijiaoArray.cpp

#include <iostream>using namespace std;void duijiaoArray(int a[][5],int* b){int i=0;int j=0;for(i=0;i<5;i++){for(j=0;j<5;j++){if(a[i][j]!=0){b[2*i+j]=a[i][j];}}}}int main(){int a[][5]={{1,2,0,0,0},{3,4,5,0,0},{0,6,7,8,0},{0,0,9,10,11},{0,0,0,12,13}};int b[13];duijiaoArray(a,b);for(int i=0;i<13;i++){cout<<b[i]<<" ";}cout<<endl;return 0;}

测试结果:

输出的是:1 2 3 4 5 6 7 8 9 10 11 12 13


四、稀疏矩阵的压缩存储

        稀疏矩阵的特点:稀疏矩阵是零元素居多的矩阵。在工程应用中,经常会遇到阶数很高的大型稀疏矩阵,如果按常规方法存储,势必会存储大量零元素,造成存储浪费。一个显然的存储方法是仅存储非零元素。假设在m*n的矩阵中,有t个非零元,那么β=t/(m*n)就叫做矩阵的稀疏因子。通常认为β<=0.5时称为稀疏矩阵。

        存储结构:通常非零元素的分布是没有规律的,为了能找到相应的元素,仅存储非零元素的值是不够的,还要存储该元素所在的行号和列号,即每个非零元素表示为三元组(行号,列号,非零元素值)。

        在C++中,可以用结构体类型来描述三元组:

struct element{int row,col;int item;};

        将稀疏矩阵的非零元素对应的三元组所构成的集合,按照行优先的顺序排成一个线性表,称为三元组表,则稀疏矩阵的压缩存储转化为三元组表的存储。

        采用顺序存储结构的三元组表称为三元组顺序表。显然,要唯一表示一个稀疏矩阵,还要存储三元组表的同时存储该矩阵的行数、列数和非零元的个数,其存储结构定义入下:

const int MaxTerm=100;struct SparseMatrix{element data[MaxTerm];int mu,nu,tu;};

sanyuanArray.cpp

void sanyuanArray(int a[][6],SparseMatrix* s){int count=0;s->mu=5;s->nu=6;int i=0;int j=0;for(i=0;i<5;i++){for(j=0;j<6;j++){if(a[i][j]!=0){s->data[count].item=a[i][j];s->data[count].row=i;s->data[count].col=j;count++;}}}}int main(){int a[5][6]={{15,0,0,22,0,-15},{0,11,3,0,0,0},{0,0,0,6,0,0},{0,0,0,0,0,0},{91,0,0,0,0,0}};SparseMatrix s;sanyuanArray(a,&s);cout<<"行 列 值"<<endl;for(int i=0;i<7;i++){cout<<s.data[i].row<<"  "<<s.data[i].col<<"  "<<s.data[i].item<<endl;}return 0;}

测试结果:


0 0
原创粉丝点击