#include <cstdio>
#include <cstdlib>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100
typedef int Status;
typedef float ElemType;
typedef struct{//三元组结构
int i, j;//非零元素行下标和列下标
ElemType e;//非零元素值
}Triple;
typedef struct{
Triple data[MAXSIZE + 1];//非零元三元组表,data[0]不用
int mu, nu, tu;//矩阵的行数、列数和非零元素个数
}TSMatrix;
TSMatrix NewMatrix(int m, int n);
//新建一个三元组表示的稀疏矩阵
Status InsertElem(TSMatrix *M, int row, int col, ElemType e);
//在三元组表示的稀疏矩阵M,第 row 行,第 col 列位置插入元素e
//插入成功,返回OK,否则返回ERROR
Status FindElem(const TSMatrix *M, int row, int col, ElemType *e);
//查找三元组表示的稀疏矩阵M中,第 row 行,第 col列元素,若不为0,
//则用e返回其值,并返回TRUE,否则返回FALSE
Status TransposeSMatrix(const TSMatrix *M, TSMatrix *T);
//采用三元组表存储表示,求稀疏矩阵M的转置矩阵T
Status FastTransposeSMatrix(const TSMatrix *M, TSMatrix *T);
//利用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T
Status MultSMatrix(const TSMatrix *M, const TSMatrix *T, TSMatrix *Q);
//稀疏矩阵的乘法,如果符合乘法规则,Q返回M*T结果,并返回OK,否则返回ERROR
void PrintSMatrix(const TSMatrix *M);
//打印稀疏矩阵所有元素
int main()
{
TSMatrix M = NewMatrix(3, 4);
TSMatrix T;
TSMatrix Q;
InsertElem(&M, 3, 2, 3.65);
InsertElem(&M, 2, 2, 2.31);
printf("
M:");
PrintSMatrix(&M);
FastTransposeSMatrix(&M, &T);
printf("
T(Transpose of M):");
PrintSMatrix(&T);
MultSMatrix(&M, &T, &Q);
printf("
M*T=");
PrintSMatrix(&Q);
return 0;
}
TSMatrix NewMatrix(int m, int n){
//新建一个三元组表示的稀疏矩阵
TSMatrix M;
M.mu = m;
M.nu = n;
M.tu = 0;
return M;
}
Status InsertElem(TSMatrix *M, int row, int col, ElemType e){
//在三元组表示的稀疏矩阵M,第 row 行,第 col 列位置插入元素e
//插入成功,返回OK,否则返回ERROR
int i, t, p;
if (M->tu >= MAXSIZE){//当前三元组表已满
printf("
Error:There is no space in the matrix;
");
return ERROR;
}
if (row>M->mu || col>M->nu || row<1 || col<1){//插入位置越界,不在1~mu或1~nu之间
printf("
Error:Insert position is beyond the arrange.
");
return ERROR;
}
p = 1;//标志新元素应该插入的位置
if (M->tu == 0){//插入前矩阵M没有非零元素
M->data[p].i = row;
M->data[p].j = col;
M->data[p].e = e;
M->tu++;
return OK;
}
for (t = 1; t <= M->tu; t++)//寻找合适的插入位置
if ((row >= M->data[t].i) && (col >= M->data[t].j))
p++;
if (row == M->data[t - 1].i && col == M->data[t - 1].j){//插入前,该元素已经存在
M->data[t - 1].e = e;
return OK;
}
for (i = M->tu; i >= p; i--){//移动p之后的元素
M->data[i + 1].i = M->data[i].i;
M->data[i + 1].j = M->data[i].j;
M->data[i + 1].e = M->data[i].e;
}
//插入新元素
M->data[p].i = row;
M->data[p].j = col;
M->data[p].e = e;
M->tu++;
return OK;
}
Status FindElem(const TSMatrix *M, int row, int col, ElemType *e){
//查找三元组表示的稀疏矩阵M中,第 row 行,第 col列元素,若不为0,
//则用e返回其值,并返回TRUE,否则返回FALSE
int p;
for (p = 1; p <= M->tu; p++)
if (M->data[p].i == row&&M->data[p].j == col){
*e = M->data[p].e;
return TRUE;
}
return FALSE;
}
Status TransposeSMatrix(const TSMatrix *M, TSMatrix *T){
//采用三元组表存储表示,求稀疏矩阵M的转置矩阵T
int col, p, q;
T->mu = M->nu; T->nu = M->mu; T->tu = M->tu;
if (T->tu){
q = 1;
for (col = 1; col <= M->mu; col++)
for (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 OK;
}
Status FastTransposeSMatrix(const TSMatrix *M, TSMatrix *T){
//利用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T
int col, t, p, q, *num, *cpot;
T->mu = M->nu; T->nu = M->mu; T->tu = M->tu;
if (T->tu){
num = (int *)malloc(sizeof(int)*M->tu);
cpot = (int *)malloc(sizeof(int)*M->tu);
if (!(num&&cpot)){
printf("Apply for memory error.
");
exit(0);
}
for (col = 1; col <= M->nu; col++) num[col] = 0;
//求M中每一列含有非零元素的个数
for (t = 1; t <= M->tu; t++) ++num[M->data[t].j];
cpot[1] = 1;
//求第col列中第一个非零元素在b.data中的序号
for (col = 2; col <= M->nu; col++)
cpot[col] = cpot[col - 1] + num[col - 1];
for (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[q].e;
++cpot[col];
}//for
}//if
return OK;
}
Status MultSMatrix(const TSMatrix *M, const TSMatrix *T, TSMatrix *Q){
//稀疏矩阵的乘法,如果符合乘法规则,Q返回M*T结果,并返回OK,否则返回ERROR
int i, j, k, p;
ElemType m, t, s;
if (M->nu != T->mu){
printf("Sorry,these two matrice can't multiply.
");
return ERROR;
}
Q->mu = M->mu; Q->nu = T->nu; Q->tu = 0;
p = 1;
for (i = 1; i <= Q->mu; i++){
for (j = 1; j <= Q->nu; j++){
s = 0;
for (k = 1; k <= M->nu; k++){
if (FALSE == FindElem(M, i, k, &m))
continue;
if (FALSE == FindElem(T, k, j, &t))
continue;
s += m*t;
}
if (s != 0){//Q[i][j]非零
Q->data[p].i = i;
Q->data[p].j = j;
Q->data[p].e = s;
p++;
Q->tu++;
}
}
}
return OK;
}
void PrintSMatrix(const TSMatrix *M){
//打印稀疏矩阵所有元素
int i, j, p = 1;
printf("
size:%d × %d
", M->mu, M->nu);
if (!M->tu){//0矩阵
printf("%g
", 0.0);
return;
}
for (i = 1; i <= M->mu; i++){
for (j = 1; j <= M->nu; j++){
if (i == M->data[p].i && j == M->data[p].j){
printf("%g ", M->data[p].e);
p++;
}
else{
printf("%g ", 0.0);
}
}
printf("
");
}
printf("
");
}