一、题目要求:
如图所示,任意输入一个稀疏矩阵M,用三元组顺序表压缩存储该稀疏矩阵M,然后求其转置矩阵T,并输出转置矩阵T。
二、问题分析
这是一个稀疏矩阵,我们采用三元组压缩存法,以下就是矩阵转置前后三元组对比:
关于矩阵转置,我们有这几种思路:
(1)简单粗暴,行列转换
//不管新三元组中行是不是从1开始,有点粗暴
void convent(TSMatrix M,TSMatrix& T)//矩阵的转置
{
int i;
T.rnum=M.cnum;
T.cnum=M.rnum;
T.num0=M.num0;
for(i=1;i<=M.num0;i++)
{
T.data[i].row=M.data[i].col;
T.data[i].col=M.data[i].row;
T.data[i].e=M.data[i].e;
}
}
(2)快速转置
核心:第 i 行第一个非零元的序号 = 第 i-1 行第一个非零元的序号 + 第 i-1 行非零元的个数
三、代码实现
#include<iostream>
#include<iomanip>//控制输出格式
using namespace std;
#define MAXSIZE 12500
typedef struct //三元组内的一个元素
{
int row;//行序
int col;//列序
int e;//数值
}Triple;
typedef struct//稀疏矩阵的非零元素
{
Triple data[MAXSIZE+1];//非0元三元组表,data[0]不使用
int rnum,cnum,num0;//行数,列数,非零元的个数
}TSMatrix;
//由二维数组创建他的三元组
void CreatMatrix(TSMatrix& M,int r,int c,int elem[100][100])
{
//三元组中元素的初始化
M.rnum=r;
M.cnum=c;
M.num0=0;
//data[0]存储行数、列数、非零元个数
M.data[0].row=r;
M.data[0].col=c;
M.data[0].e=0;
//对三元组进行赋值
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
if(elem[i][j]!=0)
{
M.data[++M.num0].e=elem[i][j];
M.data[M.num0].row=i;
M.data[M.num0].col=j;
}//if
}//for.j
}//for.i
}
void convent(TSMatrix M,TSMatrix& T)//矩阵的快速转置
{//转置---M的列 就是 T的行
//num[col]的值 代表 M 第col列 即 T 第col行 的非零元的 个数
//cpot[col]的值 代表 M 第col列 即 T 第col行 第一个非零元的序号
int i,j,col,t;
int num[M.cnum+1],cpot[M.cnum+1];//各行非零元的个数,各行第一个非零元的序号
T.rnum=M.cnum;
T.cnum=M.rnum;
T.num0=M.num0;
if(T.num0)
{
//非零元的个数矩阵 初始化
for(col=1;col<=M.cnum;++col)
num[col]=0;
//求每一列非零元的个数
for(t=1;t<=M.num0;++t)
{
//用非零元的列当该数组的角标
//每当有某列元素时,num++
++num[M.data[t].col];
}
//第一行第一个非零元的序号一定是1
cpot[1]=1;
//求第col列第一个非零元在data[]中的序号
for(col=2;col<=M.cnum;++col)
{
//第col列第一个非零元在data[]中的序号
//=上一行第一个非零元的序号 +上一行非零元的个数
cpot[col]=cpot[col-1]+num[col-1];
}
//遍历三元组
for(int p=1;p<=M.num0;++p)
{
col=M.data[p].col;//M中序号为 p的元素的列
int q=cpot[col];//T中第col行第一个非零元的 序号
T.data[q].row=M.data[p].col;
T.data[q].col=M.data[p].row;
T.data[q].e=M.data[p].e;
++cpot[col];
}//for
}//if
}
int main()
{
int rnum,cnum,i,j;
int elem[100][100]={0};
cout<<"请输入矩阵的行数和列数:"<<endl;
cin>>rnum>>cnum;
cout<<"请输入矩阵:"<<endl;
for(i=1;i<=rnum;i++)
{
for(j=1;j<=cnum;j++)
{
cin>>elem[i][j];
}
}
TSMatrix M,T;
CreatMatrix(M,rnum,cnum,elem);
convent(M,T);
cout<<"转置后的矩阵:"<<endl;
int t=1;
for(i=1;i<=cnum;i++)
{
for(j=1;j<=rnum;j++)
{
if(T.data[t].row==i&&T.data[t].col==j)
{
cout<<right<<setw(3)<<T.data[t].e;
t++;
}
else
cout<<right<<setw(3)<<'0';
}
cout<<endl;
}
}