#include <iostream>
using namespace std;
#define MTSMXSIZE 12500
#define MAXROW 10
#define MAXCOL 10
typedef int ElemType;
typedef struct
{
int i,j; //该非零元的行下标和列下标
ElemType e;
}Triple; //三元组类型
typedef struct
{
Triple data[MTSMXSIZE+1]; //非零元三元组表,dTSMtTSM[0]未用
int rpos[MTSMXSIZE+1];
int mu,nu,tu; //矩阵的行数,列数,和非零元的个数
}TSMtrix;
//打印原矩阵
ostream & operator << (ostream &ostr,TSMtrix & tsm)
{
int p,q,k=1;
for(p=1;p<=tsm.mu;p++)
{
for(q=1;q<=tsm.nu;q++)
{
if(tsm.data[k].i==p && tsm.data[k].j==q)
{
ostr<<tsm.data[k].e<<" ";
k++;
}
else
ostr<<"0 ";
}
ostr<<endl;
}
//ostr<<"*******三元组表示*******"<<endl;
//for(int i=1;i<=tsm.tu;i++)
// ostr<<tsm.data[i].i<<" "
// <<tsm.data[i].j<<" "
// <<tsm.data[i].e<<endl;
//ostr<<"************************"<<endl;
return ostr;
}
//标准转置
/*
void TransposeSMatrix(TSMtrix &tsm,TSMtrix &t)
{
t.mu=tsm.nu;
t.nu=tsm.mu;
t.tu=tsm.tu;
if(t.tu)
{
int k=1,p,q;
for(q=1;q<=tsm.nu;q++)
for(p=1;p<=tsm.tu;p++)
if(tsm.data[p].j==q)
{
t.data[k].i=tsm.data[p].j;
t.data[k].j=tsm.data[p].i;
t.data[k].e=tsm.data[p].e;
k++;
}
}
}
*/
//快速转置
void FastTransposeSMatrix(TSMtrix &tsm,TSMtrix &t)
{
t.mu=tsm.nu;
t.nu=tsm.mu;
t.tu=tsm.tu;
if(t.tu)
{
int num[MTSMXSIZE];
int cpot[MTSMXSIZE];
int col,p,q,k;
for(col=1;col<=tsm.nu;col++)
num[col]=0; //num[col]存放原矩阵每一列非零元的个数,也就是转置后的矩阵每一行的非零元的个数
//首先初始为0
for(k=1;k<=tsm.tu;++k)
++num[ tsm.data[k].j ]; //求原矩阵每一列的非零元的个数
cpot[1]=1; //第一列的第一个非零元在非零元中的编号
for(col=2;col<=tsm.nu;col++)
cpot[col] = cpot[col-1] + num[col-1]; //cpot[col]指每一列第一个非零元的序号
for(p=1;p<=tsm.tu;p++)
{
col=tsm.data[p].j; //原三元组中的第p个元素在原矩阵中的列号
q=cpot[col]; //q是原矩阵的第col列的当前的非零元素在三元组中的序号
t.data[q].i = tsm.data[p].j;
t.data[q].j = tsm.data[p].i;
t.data[q].e = tsm.data[p].e;
++cpot[col]; //变更序号,为下次做准备
}
}
}
//求tsm的rpos[]
void rpos_tsm(TSMtrix &tsm)
{
int num[MAXROW];
for(int row=1;row<=tsm.mu;row++)
num[row]=0; //num[]表示每行的非零元个数,首先置0
for(int k=1;k<=tsm.tu;++k)
++num[ tsm.data[k].i ];
//第row行的第一个非零元的位置等于前一行的第一个非零元的位置加上前一行的非零元的个数
tsm.rpos[1]=1;
for(row=2;row<=tsm.mu;row++)
tsm.rpos[row] =tsm.rpos[row-1] + num[row-1];
}
void Multsmatrix(TSMtrix &tsm1, TSMtrix &tsm2, TSMtrix &tsm3)
{
rpos_tsm(tsm1); //求tsm1的rpos[]
rpos_tsm(tsm2); //求tsm2的rpos[]
//********求乘法矩阵********//
int ctemp[MAXCOL];
int tp,t;
int p,q,ccol;
if (tsm1.nu!=tsm2.mu)
cout<<"两个矩阵的列号和行号不等"<<endl; //第一个矩阵的列数等于第二个矩阵的行数。
tsm3.mu=tsm1.mu;
tsm3.nu=tsm2.nu;
tsm3.tu=0; //q初始化,q.tu=0
if(tsm1.tu*tsm2.tu!=0) //q是非零矩阵
{
for(int arow=1;arow<=tsm1.mu;++arow) //处理M中的每一行
{
for(int col=1;col<=tsm2.nu;++col)
ctemp[col]=0; //相乘后累加的结果,起始置为0
tsm3.rpos[arow]=tsm3.tu+1; //每一行存放元素的起点
if(arow<tsm1.mu)
tp=tsm1.rpos[arow+1]; //三元组M中下一行的第一个非零元的位置
else
tp=tsm1.tu+1;
for(p=tsm1.rpos[arow];p<tp;p++) //p指向当前行的每一个非零元
{
int brow=tsm1.data[p].j;//当前行每个非零元的列号,找到对应元在N中的行号,然后处理这一行
if(brow<tsm2.mu)
t=tsm2.rpos[brow+1]; //三元组N中下一行的第一个非零元的位置
else
t=tsm2.tu+1;
for(q=tsm2.rpos[brow];q<t;q++)
{
ccol=tsm2.data[q].j; //ccol指三元组N中的非零元的列标,即乘积应该放到应该放在的位置
ctemp[ccol] += tsm1.data[p].e * tsm2.data[q].e;
}
}
for(ccol=1;ccol<=tsm3.nu;++ccol)
if(ctemp[ccol]) //如果累加器中的以ccol为列标的元素不为0,那么存入到乘积三元组中
{
tsm3.tu++;
tsm3.data[tsm3.tu].i = arow;
tsm3.data[tsm3.tu].j = ccol;
tsm3.data[tsm3.tu].e = ctemp[ccol];
}//if ctemp
}//for arow
}//if
}
int main()
{
TSMtrix TSM1; //原矩阵
//TSMtrix T; //转置矩阵
TSMtrix TSM2; //相乘矩阵
TSMtrix TSM3; //乘后矩阵
int k;
cout<<"请输入矩阵TSM1的行,列,非零元的个数(不超过10且不为0):"<<endl;
cin>>TSM1.mu>>TSM1.nu>>TSM1.tu;
for(k=1;k<=TSM1.tu;k++)
{
cout<<"请输入第"<<k<<"个数的情况,所在的行,列以及它的值:"<<endl;
cin >>TSM1.data[k].i
>>TSM1.data[k].j
>>TSM1.data[k].e;
}
cout<<"TSM1原矩阵:"<<endl;
cout<<TSM1<<endl;
//TransposeSMatrix(TSM1,T);
//cout<<T<<endl;
//FastTransposeSMatrix(TSM1,T); //快速转置
//cout<<"转置后的矩阵:"<<endl;
//cout<<T<<endl;
int g;
cout<<"请输入矩阵TSM2的行,列,非零元的个数(不超过10且不为0):"<<endl;
cin>>TSM2.mu>>TSM2.nu>>TSM2.tu;
for(g=1;g<=TSM2.tu;g++)
{
cout<<"请输入第"<<g<<"个数的情况,所在的行,列以及它的值:"<<endl;
cin >>TSM2.data[g].i
>>TSM2.data[g].j
>>TSM2.data[g].e;
}
cout<<"TSM2原矩阵:"<<endl;
cout<<TSM2<<endl;
Multsmatrix(TSM1 , TSM2 , TSM3);
cout<<TSM3<<endl;
return 0;
}
数据结构——稀疏矩阵
最新推荐文章于 2023-04-18 15:31:00 发布