您的位置:首页 > 其它

稀疏矩阵——行逻辑连接的顺序三元组表

2014-08-14 16:28 288 查看
#include<iostream>
using namespace std;

#define MAXSIZE 20
#define MAXNUM 20
#define MAXCPOT 20
#define MAXRC 20
#define MAXCTEMP 20
#define ok 1
#define error 0
typedef int Status;

template<class T>
class Triple{
template<class T> friend class RLTSMatrix;
private:
int i,j;	//i,j表示该非零元的行和列下标
T	e;		//非零元素的值
};

//-------------稀疏矩阵的基本操作的函数原型说明---------------
template<class T>
class RLTSMatrix{
public:
//TSMatrix();
Status CreateSMatrix();	//创建稀疏矩阵M
Status DesSMatrix();	//销毁稀疏矩阵
Status FirstPos();		//各行第一个非零元的位置表
Status PrintSMatrix();	//输出稀疏矩阵
Status MultSMatrix(RLTSMatrix<T> N,RLTSMatrix<T> &Q);//求稀疏矩阵的积Q=M*N
private:
Triple<T> *data;
int rpos[MAXRC+1];
int row,col,num;	//矩阵的行数、列数和非零元个数
};

//--------------------稀疏矩阵的基本操作的函数实现---------------------
template<class T>
Status RLTSMatrix<T>::CreateSMatrix()
{
cout<<"输入矩阵的行数row= ";cin>>row;
cout<<"\n"<<"输入矩阵的列数col= ";cin>>col;
cout<<"\n"<<"输入矩阵非零元个数num= ";cin>>num;cout<<endl;
if(num>(row*col))	//非零元个数大于矩阵元素总数
exit(-1);
data=new Triple<T>[num+1];
if(!data)	//分配失败
exit(-1);
cout<<"以(行,列,值)的形式输入非零三元组:"<<endl;
for(int i=1;i<=num;i++)
{
cin>>(data+i)->i>>(data+i)->j>>(data+i)->e;
if((data+i)->i>row||(data+i)->j>col)
{
cout<<"!!错误:非零元的行或列值输入有误"<<endl;
exit(-1);
}//if
}//for
return ok;
}//CreateSmatrix

template<class T>
Status RLTSMatrix<T>::PrintSMatrix()
{
int k=1;
for(int i=1;i<=row;i++)
{
for(int j=1;j<=col;j++)
{
if(i==(data+k)->i&&j==(data+k)->j&&k<=num) //该元素为非零元
{
cout.width(5);
cout.setf(ios::left);
cout<<(data+k)->e<<" "; k++;
}//if
else
{
cout.width(5);
cout.setf(ios::left);
cout<<0<<" ";
}//else
}//for
cout<<endl;	//矩阵一行的元素输出完后换行
}//for
cout<<"矩阵每行的第一个非零元的位置表如下:";
for(int i=1;i<=row;i++)
cout<<"("<<i<<":"<<rpos[i]<<") ";
cout<<endl;
return ok;
}//PrintSMatrix

template<class T>
Status RLTSMatrix<T>::FirstPos()
{
int rrow,count[MAXNUM];
for(rrow=1;rrow<=row;rrow++)//初始化每一行中非零元个数为0
count[rrow]=0;
for(int t=1;t<=num;t++)
++count[(data+t)->i];	//求矩阵中每一行非零元个数
rpos[1]=1;	//第一行第一个非零元的位置
for(rrow=2;rrow<=row;rrow++)
rpos[rrow]=rpos[rrow-1]+count[rrow-1];
rpos[rrow]=num+1;//此时rrow指向row+1行,最后一行最后一个非零元位置即为num,假设rrow行存在非零元
//则其位置为num+1,目的是为了遍历最后一行非零元时作为结束的标志
return ok;
}//FirstPos

template<class T>
Status RLTSMatrix<T>::DesSMatrix()
{
if(data)
{
delete data;
data=NULL;
row=0;col=0;num=0;
}//if
return ok;
}//DesSMatrix

template<class T>
Status RLTSMatrix<T>::MultSMatrix(RLTSMatrix<T> N,RLTSMatrix<T> &Q)
{
int m,n,arow,arrow,brow,t,ccol,ctemp[MAXCTEMP];
if(col!=N.row)
exit(-1);
Q.row=row;Q.col=N.col;Q.num=0;
if(num*N.num!=0)	//Q是非零矩阵
{
Q.data=new Triple<T>[num*N.num+1];

for(arow=1;arow<=row;arow++)//处理M的每一行
{
for(arrow=1;arrow<=Q.col;arrow++)//当前行各元素累加器为0
ctemp[arrow]=0;
Q.rpos[arow]=Q.num+1;
for(m=rpos[arow];m<rpos[arow+1];m++)//对当前行中的每一个非零元
{
brow=(data+m)->j;//找到对应元在N中的行号
if(brow<N.row)	//不是最后一行
t=N.rpos[brow+1];//t为brow行下一行第一个非零元的位置
else			//brow是最后一行
t=N.num+1;	//最后一行最后一个非零元位置即为N.num
for(n=N.rpos[brow];n<t;n++)//N中对应行的所有非零元
{
ccol=(N.data+n)->j;//乘积元素在Q中的列号
ctemp[ccol]+=((data+m)->e)*((N.data+n)->e);
}//for
}//for
for(ccol=1;ccol<=Q.col;ccol++)//压缩存储该行非零元
{
if(ctemp[ccol])
{
if(++Q.num>MAXSIZE)
return error;
(Q.data+Q.num)->i=arow;(Q.data+Q.num)->j=ccol;
(Q.data+Q.num)->e=ctemp[ccol];
}//if
}//for
}//for
}//if
return ok;
}//MultSMatrix

void main()
{
RLTSMatrix<int> M,N,Q;
M.CreateSMatrix();
M.FirstPos();
cout<<"矩阵M:"<<endl;
M.PrintSMatrix();
N.CreateSMatrix();
N.FirstPos();
cout<<"矩阵N:"<<endl;
N.PrintSMatrix();
M.MultSMatrix(N,Q);
cout<<"矩阵Q=M*N:"<<endl;
Q.PrintSMatrix();
}//main

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐