稀疏矩阵的压缩存储及运算
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
稀疏矩阵的压缩存储及运算
一、实验内容
实现稀疏矩阵的压缩存储方法以及在特定存储方法下的基本运算
二、实验母的
掌握数组的应用,包括稀疏矩阵、特殊矩阵的压缩存储方法。
矩阵的基本运算的实现,包括矩阵相加、转置、乘法等。
三、问题描述
1)用行逻辑链接顺序表和十字链表分别实现稀疏矩阵的压缩存储
2)编程实现矩阵的转置运算和乘法运算(运用行逻辑链接顺序表或十字链表作为存储结构)
四、问题的实现
稀疏矩阵的抽象数据类型定义:
ADT SpareseMatrix{
数据对象:;,,2,1;,,2,1|{n j m i D a ij ===
},,列数分别称为矩阵的行数和和n m ElemSet a j i ∈
数据关系: :}1,11|,{}
11,1|,{}
,{,1,1,,n j m i Col n j m i Row Col Row R a a a a j i j i j i j i ≤≤-≤≤><=-≤≤≤≤><==++
基本操作:
CreateSMatrix(&M);
操作结果:创建稀疏矩阵M 。
PrintSMatrix(M);
初始条件:稀疏矩阵M 存在。
操作结果:输出稀疏矩阵M 。
AddSMatrix(M ,N ,&Q);
初始条件:稀疏矩阵M 和N 的行数和列数对应相等。
操作结果:求稀疏矩阵的和Q=M+N 。
MultSMatrix(M ,N ,&Q);
初始条件:稀疏矩阵M 的列数等于N 的行数。
操作结果:求稀疏矩阵乘积Q=M*N 。
TransposeSMatrix(M,&T);
初始条件:稀疏矩阵M 存在。
操作结果:求稀疏矩阵M 的转置矩阵T 。
}ADT SpareseMatrix
五、主要源程序代码
#include <iostream>
using namespace std;
#define MAXSIZE 100;
typedef struct OLNode{
int i,j;
int e;
struct OLNode *right,*down;
}OLNode,*OLink;
typedef struct{
OLink *rhead,*chead;
int mu,nu,tu;
}CrossList; //十字链表结构体定义
int CreatSMatrix_OL(CrossList &M){
int i,j,e;
OLink q;
OLink p;
cout<<"请输入稀疏矩阵的行数,列数,非零元素的个数:";
cin>>M.mu;cin>>M.nu;cin>>M.tu;
M.rhead=(OLink *)malloc((M.mu+1)*sizeof(OLNode));
M.chead=(OLink *)malloc((M.nu+1)*sizeof(OLNode));
for(i=1;i<=M.mu;i++) M.rhead[i]=NULL;
for(i=1;i<=M.nu;i++) M.chead[i]=NULL;
cout<<"请输入稀疏矩阵,若为空,则退出"<<endl;
cin>>i;cin>>j;cin>>e;
while (i!=0){
p=(OLink)malloc(sizeof(OLNode));
p->i=i;p->j=j;p->e=e;
if (M.rhead[i]==NULL || M.rhead[i]->j>j) {p->right=M.rhead[i];M.rhead[i]=p;}
else{
q=M.rhead[i];
while (q->right && q->right->j<j)
q=q->right;
p->right=q->right;
q->right=p;}
if (M.chead[j]==NULL || M.chead[j]->i>i) {p->down=M.chead[j];M.chead[j]=p;}
else{
q=M.chead[j];
while (q->down && q->down->i<i)
q=q->down;
p->down=q->down;
q->down=p;
}
cin>>i;cin>>j;cin>>e;
}
} //创建十字链表
void TurnSMatrix_OL(CrossList &M){
int a,b;
OLink p,q;
for(a<1;a<=M.mu;a++)
{
q=p=M.rhead[a];
while(q){
b=p->i;
p->i=p->j;
p->j=b;
q=p->right;
p->right=p->down;
p->down=q;
}
}
} //十字链表实现稀疏矩阵转置
int AddSMatrix_OL(CrossList *A,CrossList *B){
OLNode *pa,*pb,*p,*pre,*cp[100];
int i,j,t;
t=A->tu+B->tu;
for(j=1;j<=A->nu;j++) cp[j]=A->chead[j];
for(i=1;i<=A->mu;i++){
pa=A->rhead[i];
pb=B->rhead[i];
pre=NULL;
while(pb){
if(pa==NULL || pa->j>pb->j){
p=(OLink)malloc(sizeof(OLNode));
if(!pre)A->rhead[i]=p;
else pre->right=p;
p->right=pa;
pre=p;
p->i=i;p->j=pb->j;p->e=pb->e;
if(!A->chead[p->j]){
A->chead[p->j]=cp[p->j]=p;
p->down=NULL;
}
else{
cp[p->j]->down=p;
cp[p->j]=p;
}
pb=pb->right;
}
else if(pa->j<pb->j) {pre=pa;pa=pa->right;}
else if(pa->e+pb->e){
t--;
pa->e+=pb->e;
pre=pa;
pa=pa->right;
pb=pb->right;}
else{
t=t-2;
if(!pre)A->rhead[i]=pa->right;
else pre->right=pa->right;
p=pa;pa=pa->right;
if(A->chead[p->j]==p) A->chead[p->j]=cp[p->j]=p->down;
else cp[p->j]->down=p->down;
free(p);
pb=pb->right;
}
}
}
A->mu=A->mu>B->mu? A->mu:B->mu;
A->nu=A->nu>B->nu? A->nu:B->nu;
return 1;
} //十字链表实现两稀疏矩阵相加
int MultSMatrix_OL(CrossList M,CrossList N,CrossList &Q){
int i,j,e;
OLink p0,q0,p,p1,p1a;
if(M.nu!=N.mu)
{
cout<<"稀疏矩阵A的列数和B的行数不相等,不能相乘";
return 0;
}
Q.mu=M.mu;Q.nu=N.nu;Q.tu=0;
if(!(Q.rhead=(OLink *)malloc((Q.mu+1)*sizeof(OLink))))exit(-2);
if(!(Q.chead=(OLink *)malloc((Q.nu+1)*sizeof(OLink))))exit(-2);
for(i=1;i<=Q.mu;i++) Q.rhead[i]=NULL;
for(i=1;i<=Q.nu;i++) Q.chead[i]=NULL;
for(i=1;i<=Q.mu;i++)
for(j=1;j<=Q.nu;j++)
{
p0=M.rhead[i];q0=N.chead[j];e=0;
while(p0 && q0)
{
if(p0->j>q0->i) q0=q0->down;
else if(p0->j<q0->i) p0=p0->right;
else{
e+=p0->e*q0->e;
q0=q0->down;p0=p0->right;
}
}
if(e)
{
if(!(p=(OLink)malloc(sizeof(OLNode))))exit(-2);
Q.tu++;
p->i=i;p->j=j;p->e=e;p->right=NULL;p->down=NULL;
if(Q.rhead[i]==NULL)
Q.rhead[i]=p1=p;
else p1->right=p;p1=p;
if(Q.chead[j]==NULL)
Q.chead[j]=p;
else{
p1a=Q.chead[j];
while(p1a->down)
p1a=p1a->down;p1a->down=p;
}
}
}
return 1;
} //十字链表实现两稀疏矩阵相乘
int ShowSMatrix(CrossList *A){
int a;
OLink p;
for(a=1;a<=A->mu;a++)
if(A->rhead[a]) {p=A->rhead[a];}
while(p){
printf("%3d%3d%3d\n",p->i,p->j,p->e);p=p->right;}
return 1;
} //十字链表显示
void main()
{
int n;
char c;
CrossList MM,TT,SS;
CreatSMatrix_OL(MM);
cout<<"您输入的稀疏矩阵(只列出非零元素):"<<endl;
cout<<"行列大小"<<endl;
ShowSMatrix(&MM);
cout<<"请选择操作:"<<endl;
cout<<"1:实现稀疏矩阵的转置"<<endl;
cout<<"2:实现两稀疏矩阵的相加"<<endl;
cout<<"3:实现两稀疏矩阵的相乘"<<endl;
cout<<"4:退出程序"<<endl;
cin>>n;
switch(n){
case 1:
TurnSMatrix_OL(MM);
cout<<"转置后的稀疏矩阵:行列大小"<<endl;
ShowSMatrix(&MM);
break;
case 2:
cout<<"请输入另一个稀疏矩阵:"<<endl;
CreatSMatrix_OL(TT);
AddSMatrix_OL(&MM,&TT);
cout<<"相加后的矩阵为:"<<endl;
ShowSMatrix(&MM);
break;
case 3:
cout<<"请输入另一个稀疏矩阵:"<<endl;
CreatSMatrix_OL(TT);
MultSMatrix_OL(MM,TT,SS);
cout<<"相乘后的矩阵为:"<<endl;
ShowSMatrix(&SS);
break;
case 4:
exit(0);
default:cout<<"error!"<<endl;
}
system("pause");
}
六、总结
整个实验中学会了稀疏矩阵的压缩存储方法,用十字链表来存储,以及在特定存储方法下的基本运算。