稀疏矩阵的十字链表表示法及其加法减法运算算法

本文介绍了一种使用十字链表表示的稀疏矩阵,并实现了矩阵的加法和减法操作。通过链表节点存储非零元素及其位置信息,有效地减少了存储空间的需求。程序包括创建矩阵、输出矩阵以及进行矩阵加减法的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include<iomanip>
using namespace std;
#define ERROR -1


typedef struct OLNode{
int i,j,e;
struct OLNode *right,*down;
}OLNode,*OLink;


typedef struct{
OLink *rhead,*chead;
int mu,nu,tu;
}CrossList;
int CreatMartix(CrossList &L){
int m,n,t;
cout<<"请输入矩阵行数,列数,非零个数";
cin>>m>>n>>t;
L.mu=m;
L.nu=n;
L.tu=t;
L.rhead=(OLink*)malloc((m+1)*sizeof(OLink));
if(!L.rhead)return ERROR;
for(m=0;m<L.mu+1;m++) L.rhead[m]=NULL;
L.chead=(OLink*)malloc((n+1)*sizeof(OLink));
if(!L.rhead)return ERROR;
for(m=0;m<L.nu+1;m++) L.chead[m]=NULL;
cout<<"请输入费单元的下标与数值";
for(m=0;m<L.tu;m++){
int x,y,z;
cin>>x>>y>>z;
OLink p;
p=(OLink)malloc(sizeof(OLNode));
if(!p)return 0;
p->i=x;
p->j=y;
p->e=z;
p->right=NULL;
p->down=NULL;
if(L.rhead[x]==NULL||L.rhead[x]->j>p->j)
{
p->right=L.rhead[x];
L.rhead[x]=p;
}
else if(L.rhead[x]->j<p->j)
{
OLink A;
for(A=L.rhead[x];A->right&&A->right->j<p->j;A=A->right);
p->right=A->right;
A->right=p;

}
if(L.chead[y]==NULL||L.chead[y]->i>p->i){
p->down=L.chead[y];
L.chead[y]=p;
}
else if(L.chead[y]->i<p->i){
OLink B;
for(B=L.chead[y];B->down&&B->down->i<p->i;B=B->down);
p->down=B->down;
B->down=p;

}
}
return 0;
}
int add(CrossList &A,CrossList&B){
int v=1;OLink *hl;hl=(OLink*)malloc(A.nu*sizeof(OLink));
while(v<=A.nu){hl[v]=A.chead[v];v++;}
for(v=1;v<=A.mu;v++){
OLink pa,pb,p,pre;
pre=NULL;
pa=A.rhead[v];
pb=B.rhead[v];               
while(pb){
p=(OLink)malloc(sizeof(OLNode));
p=pb;
 
if(pa==NULL||pa->j>pb->j)
{pb=pb->right;
if(pre==NULL){
p->right=pa;
A.rhead[v]=p;
pre=p;
}
else{
   p->right=pre->right;
pre->right=p;
pre=p;
                }
if(A.chead[p->j]==NULL||A.chead[p->j]->i>p->i)
{
p->down=A.chead[p->j];
A.chead[p->j]=p;
hl[p->j]=p;
}
else
{  
p->down=hl[p->j]->down;
hl[p->j]->down=p;
hl[p->j]=p;
}

}
 else if(pa!=NULL&&pa->j<pb->j)
{
hl[pa->j]=pa;
pre=pa;
pa=pa->right; 
}
else if(pa->j==pb->j&&pa->e+pb->e==0)
{
if(pre==NULL){
A.rhead[v]=pa->right;
pa=pa->right;
pb=pb->right;
}
else{
pre->right=pa->right;
pa=pa->right;
pb=pb->right;
}
if(A.chead[p->j]->i==p->i)
{
A.chead[p->j]=A.chead[p->j]->down;
hl[p->j]=A.chead[p->j];}
else{
hl[p->j]->down=pa->down;}

}
     else if (pa->j==pb->j&&pa->e+pb->e!=0)

hl[p->j]=pa;
pa->e+=pb->e;
pre=pa;
pa=pa->right;
pb=pb->right;
}

}
}
return 0;
}





int shuchu(CrossList& L){
for(int i=1;i<=L.mu;i++){
if(!L.rhead[i]){
for( int v=1;v<=L.nu;v++)
cout<<setw(4)<<0;
}
OLink pa=L.rhead[i];
if(pa&&pa->j>1)
{
int j=pa->j-1;
while(j--)cout<<setw(4)<<0;
}
while(pa)
{
if(!pa->right)
{
cout<<setw(4)<<pa->e;
if(pa->j<L.nu)
{int m=L.nu-pa->j;
while(m--)
cout<<setw(4)<<0;
}break;
}
else
{
cout<<setw(4)<<pa->e;
if(pa->right->j-pa->j>1)
{
int n=pa->right->j-pa->j-1;
while(n--)cout<<setw(4)<<0;
}
pa=pa->right;
}
}
cout<<endl;
}
return 0;
}


int jianfa(CrossList &A,CrossList&B){
int v=1;OLink *hl;hl=(OLink*)malloc(A.nu*sizeof(OLink));
while(v<=A.nu){hl[v]=A.chead[v];v++;}
for(v=1;v<=A.mu;v++){
OLink pa,pb,p,pre;
pre=NULL;
pa=A.rhead[v];
pb=B.rhead[v];               
while(pb){
p=(OLink)malloc(sizeof(OLNode));
p=pb;
p->e=-(pb->e);
if(pa==NULL||pa->j>pb->j)
{pb=pb->right;
if(pre==NULL){
p->right=pa;
A.rhead[v]=p;
pre=p;
}
else{
   p->right=pre->right;
pre->right=p;
pre=p;
                }
if(A.chead[p->j]==NULL||A.chead[p->j]->i>p->i)
{
p->down=A.chead[p->j];
A.chead[p->j]=p;
hl[p->j]=p;
}
else
{  
p->down=hl[p->j]->down;
hl[p->j]->down=p;
hl[p->j]=p;
}

}
 else if(pa!=NULL&&pa->j<pb->j)
{
hl[pa->j]=pa;
pre=pa;
pa=pa->right; 
}
else if(pa->j==pb->j&&pa->e+pb->e==0)
{
if(pre==NULL){
A.rhead[v]=pa->right;
pa=pa->right;
pb=pb->right;
}
else{
pre->right=pa->right;
pa=pa->right;
pb=pb->right;
}
if(A.chead[p->j]->i==p->i)
{
A.chead[p->j]=A.chead[p->j]->down;
hl[p->j]=A.chead[p->j];}
else{
hl[p->j]->down=pa->down;}

}
     else if (pa->j==pb->j&&pa->e+pb->e!=0)

hl[p->j]=pa;
pa->e+=pb->e;
pre=pa;
pa=pa->right;
pb=pb->right;
}

}
}
return 0;
}







int main(){
cout<<"------------矩阵加法-----------"<<endl;
CrossList P,Q;
CreatMartix(P);
cout<<"矩阵P"<<endl;
shuchu(P);
    CreatMartix(Q);
cout<<"矩阵Q"<<endl;
shuchu(Q);
cout<<endl<<endl;
add(P,Q);
cout<<"矩阵P+Q:";
cout<<endl; 
shuchu(P);
cout<<endl;
cout<<"------------矩阵减法-----------"<<endl;
CrossList C,D;
CreatMartix(C);
cout<<"矩阵C:"<<endl;
shuchu(C);
    CreatMartix(D);
cout<<"矩阵D:"<<endl;
shuchu(D);
cout<<endl<<endl;
jianfa(C,D);
cout<<"矩阵C-D:";
cout<<endl; 
shuchu(C);
return 0;
}
十字链表是一种用于表示稀疏矩阵的数据结构,它可以高效地存储和处理稀疏矩阵。 在进行十字链表稀疏矩阵加法时,我们需要进行以下步骤: 1. 创建两个稀疏矩阵十字链表表示。 2. 初始化一个新的十字链表来存储结果矩阵。 3. 遍历两个输入矩阵的十字链表,同时进行如下操作: a. 如果两个链表的行号和列号相等,说明有相同的元素可以相加,将它们的值相加,并将结果插入到结果链表中。 b. 如果链表1的行号小于链表2的行号,说明链表1中存在元素而链表2中不存在,直接将链表1的元素插入结果链表中。 c. 如果链表2的行号小于链表1的行号,说明链表2中存在元素而链表1中不存在,直接将链表2的元素插入结果链表中。 4. 返回结果链表作为结果矩阵。 这样,我们就可以实现两个稀疏矩阵加法操作。 当进行稀疏矩阵加法时,可能会遇到以下问题: 1. 如何创建十字链表表示稀疏矩阵:可以使用一个结构体来表示每个非零元素,结构体包含行号、列号和值等信息。然后,使用链表来存储这些结构体,同时使用一维数组来存储每个行和列的头指针。 2. 如何处理两个链表的合并:可以使用双指针来遍历两个链表,根据行号和列号的大小关系来决定插入哪个元素到结果链表中,然后将指针移动到下一个节点。 3. 如何处理相同位置的元素相加:可以直接将两个元素的值相加,并将结果插入到结果链表中。 相关问题: 1. 如何实现稀疏矩阵的乘法? 2. 如何实现稀疏矩阵的转置? 3. 如何实现稀疏矩阵的压缩存储? 4. 如何实现稀疏矩阵的逆转?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值