1)掌握稀疏矩阵基础知识,实现初始化稀疏矩阵、销毁稀疏矩阵、输出稀疏矩阵、复制稀疏矩阵、稀疏矩阵的相加、相减与相乘、将指定值插入到稀疏矩阵的指定位置、返回指定稀疏矩阵的指定行列的值等操作;
2)掌握稀疏矩阵简单转置方法和快速转置方法的实现。
#include <iostream>
#define MAXSIZE 12500//假设非零元素的最大值为12500
typedef int ElemType;
using namespace std;
typedef struct {
int i,j;//该元素的行下标和列下标
ElemType e;
}Triple,*pTriple;
typedef struct{
Triple data[MAXSIZE+1];//非零元三元组表,data[0]未用
int mu,nu,tu;//矩阵的行数 列数 和 非零元素个数
}TSMatrix;
bool initMatrix(TSMatrix &M);//初始化稀疏矩阵
bool DestroySMatrix(TSMatrix &M);//销毁稀疏矩阵
bool PrintSMatrix(TSMatrix &M);//输出稀疏矩阵
bool CopySMatrix(TSMatrix &M,TSMatrix &T);//由稀疏矩阵M复制得到T
bool AddSMatrix(TSMatrix &M,TSMatrix &N,TSMatrix &Q);//当稀疏矩阵M与N的行数和列数对应相等时,求稀疏矩阵的和Q=M+N
bool SubMatrix(TSMatrix &M,TSMatrix &N,TSMatrix &Q);//当稀疏矩阵M与N的行数和列数对应相等时,求稀疏矩阵的差Q=M-N
bool MultSMatrix(TSMatrix &M,TSMatrix &N,TSMatrix &Q);//当稀疏矩阵M的列数与N的行数对应相等时,求稀疏矩阵乘积Q=M X N;
bool TransposeSMatrix1(TSMatrix &M,TSMatrix &T);//求稀疏矩阵M的转置矩阵T
bool TransposeSMatrix2(TSMatrix &M,TSMatrix &T); //求稀疏矩阵M的快速转置矩阵T
bool setItem(TSMatrix &M,int i,int j,ElemType e);//将指定值插入到稀疏矩阵的指定位置
void getItem(TSMatrix &M,int i,int j,int &x);//返回指定稀疏矩阵的指定行列的值
int main(){
TSMatrix A;
if (initMatrix(A)){
cout << "初始化稀疏矩阵A成功" << endl;
}
PrintSMatrix(A);
TSMatrix B;
cout << "A矩阵复制得B矩阵" << endl;
CopySMatrix(A,B);
PrintSMatrix(B);
TSMatrix C;
AddSMatrix(A,B,C);
cout << "当A矩阵与B矩阵相加时,得到C矩阵" << endl;
PrintSMatrix(C);
TSMatrix D;
SubMatrix(C,A,D);
cout << "当C矩阵与A矩阵相减时,得到D矩阵" << endl;
PrintSMatrix(D);
TSMatrix E;
cout << "初始化E矩阵,要求行数为3,可实现与A矩阵的相乘" << endl;
initMatrix(E);
TSMatrix F;
MultSMatrix(A,E,F);
cout << "当A与E矩阵相乘时,得到F矩阵" << endl;
PrintSMatrix(F);
TSMatrix G;
cout << "当A矩阵转置时,得到G矩阵" << endl;
cout << "用简单转置方法转置" << endl;
TransposeSMatrix1(A,G);
PrintSMatrix(G);
TSMatrix H;
cout << "用快速转置方法转置" << endl;
TransposeSMatrix2(A,H);
PrintSMatrix(H);
DestroySMatrix(A);
DestroySMatrix(B);
DestroySMatrix(C);
DestroySMatrix(D);
DestroySMatrix(E);
DestroySMatrix(F);
DestroySMatrix(G);
DestroySMatrix(H);
return 0;
}
//初始化稀疏矩阵
bool initMatrix(TSMatrix &M){
int x,y,z;
cout << "请依次输入稀疏矩阵的行数 列数 非零元素个数" << endl;
cin>>x>>y>>z;
M.mu = x;
M.nu = y;
M.tu = z;
for(int k=1;k<=M.tu;k++){
cout<<"请输入第"<<k<<"个元素所在行数、列数、值"<<endl;
cin>>x>>y>>z;
M.data[k].i = x;
M.data[k].j = y;
M.data[k].e = z;
}
return true;
}
//销毁稀疏矩阵
bool DestroySMatrix(TSMatrix &M){
for(int k=1;k<=M.tu;k++){
M.data[k].i = 0;
M.data[k].j = 0;
M.data[k].e = 0;
}
M.mu = 0;
M.nu = 0;
M.tu = 0;
return true;
}
//输出稀疏矩阵
bool PrintSMatrix(TSMatrix &M){
cout << "此时该三元组为" << endl;
for(int k=1;k<=M.tu;k++){
cout << M.data[k].i << " " << M.data[k].j << " " << M.data[k].e;
cout << endl;
}
return true;
}
//由稀疏矩阵M复制得到T
bool CopySMatrix(TSMatrix &M,TSMatrix &T){
T.mu = M.mu;
T.nu = M.nu;
T.tu = M.tu;
for(int k=1;k<=M.tu;k++){
T.data[k].i = M.data[k].i ;
T.data[k].j = M.data[k].j;
T.data[k].e = M.data[k].e;
}
return true;
}
//当稀疏矩阵M与N的行数和列数对应相等时,求稀疏矩阵的和Q=M+N
bool AddSMatrix(TSMatrix &M,TSMatrix &N,TSMatrix &Q){
if(M.mu!=N.mu||M.nu!=N.nu){
cout << "输入错误" << endl;
return false;
}
Q.mu = M.mu;
Q.nu = M.nu;
Q.tu =0;
int item,x,y;
for(int i=1;i<=M.mu;i++){
for(int j=1;j<=M.nu;j++){
getItem(M,i,j,x);
getItem(N,i,j,y);
item = x + y;
//如果计算出来的值不为零, 则插入到稀疏矩阵中
if(item != 0){
setItem(Q,i,j,item);
}
}
}
return true;
}
//当稀疏矩阵M与N的行数和列数对应相等时,求稀疏矩阵的差Q=M-N
bool SubMatrix(TSMatrix &M,TSMatrix &N,TSMatrix &Q){
if(M.mu!=N.mu||M.nu!=N.nu){
cout << "输入错误" << endl;
return false;
}
Q.mu = M.mu;
Q.nu = M.nu;
Q.tu = 0;
int item,x,y;
for(int i=1;i<=M.mu;i++){
for(int j=1;j<=M.nu;j++){
getItem(M,i,j,x);
getItem(N,i,j,y);
item = x - y;
//如果计算出来的值不为零, 则插入到稀疏矩阵中
if(item != 0){
setItem(Q,i,j,item);
}
}
}
return true;
}
//稀疏矩阵M的列数与N的行数对应相等时,直接用三元组方式求矩阵乘积
bool MultSMatrix(TSMatrix &M,TSMatrix &N,TSMatrix &Q){
if(M.nu != N.mu)
return false;
Q.mu = M.mu;
Q.nu = N.nu;
Q.tu = 0;//Q初始化
int sum,x,y;
for(int i=1;i<=Q.mu;i++){
for(int j=1;j<=Q.nu;j++){
sum = 0;
for(int k=1;k<=N.mu;k++){
getItem(M,i,k,x);
getItem(N,k,j,y);
sum += x * y;
}
setItem(Q,i,j,sum);
}
}
return true;
}
//求稀疏矩阵M的简单转置矩阵T
bool TransposeSMatrix1(TSMatrix &M,TSMatrix &T){
T.mu = M.nu;
T.nu = M.mu;
T.tu = M.tu;
int num[MAXSIZE+1];
if(T.tu){
int q = 1;
for(int col=1;col<=M.nu;++col){
for(int p=1;p<=M.tu;++p){
if(M.data[p].j == col){
T.data[q].i = M.data[p].j;
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
++q;
}
}
}
}
return true;
}
//求稀疏矩阵M的快速转置矩阵T
bool TransposeSMatrix2(TSMatrix &M,TSMatrix &T){
T.mu = M.nu;
T.nu = M.mu;
T.tu = M.tu;
int num[MAXSIZE+1];
if(T.tu){
for(int col=1;col<=M.nu;++col){
num[col] = 0;//num[col]表示矩阵中第col列中非零元的个数
}
for(int t=1;t<=M.tu;++t)
++num[M.data[t].j];//求M中每一列含非零元个数
int cpot[MAXSIZE+1];
cpot[1] = 1;
//求第col列中第一个非零元在b.data中的序号
for(int col=2;col<=M.nu;++col){
cpot[col] = cpot[col-1]+num[col-1];//cpot[col]表示该列第一个非零元素在三元组表中存放的正确位置
}
int col;
int q;
for(int p=1;p<=M.tu;++p){
col = M.data[p].j;
q = cpot[col];
T.data[q].i = M.data[p].j;
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
++cpot[col];
}
}
return true;
}
//将指定值插入到稀疏矩阵的指定位置
bool setItem(TSMatrix &M,int i,int j,ElemType e){
if(M.mu<i||M.nu<j){
cout << "输出错误";
return false;
}
if(M.tu == MAXSIZE){
cout << "三元组已满,不能继续存储元素" << endl;
return false;
}
if(e == 0){//当存入的元素值为0时,则直接返回
return true;
}
int index = 0;
while(index <= M.tu){
if(i > M.data[index].i){
index++;
}
else if((i == M.data[index].i) && (j > M.data[index].j)){
index++;
}
else{
break;
}
}
if((i == M.data[index].i)&&(j == M.data[index].j)){//当前行列已经存在时,则直接替换该行列的元素
M.data[index].e = e;
}else{//当前行列不存在时
M.tu++;
for(int m = M.tu;m>index;m--){
M.data[m].i = M.data[m-1].i;
M.data[m].j = M.data[m-1].j;
M.data[m].e = M.data[m-1].e;
}
M.data[index].i = i;
M.data[index].j = j;
M.data[index].e = e;
}
}
//返回指定稀疏矩阵的指定行列的值
void getItem(TSMatrix &M,int i,int j,int &m){
int k = 1;
if(i>M.mu||j>M.nu){
cout << "输入错误";
exit(-1);
}
while((k<M.tu)&&(i>M.data[k].i)){
k++;//查找i行的非零元素
}
while((k<=M.tu)&&(i==M.data[k].i)&&(j>M.data[k].j)){
k++;
}//此时
if((M.data[k].i==i)&&(M.data[k].j==j)){
m = M.data[k].e;
}
else{
m = 0;
}
}