SparseMatrix.h
#include<cstdio>
#define maxTerms 30
typedef int DataType;
typedef struct {
int row, col;
DataType value;
}Triple;
typedef struct {
int Rows, Cols, Terms; //三元组行数,列数,元素个数
Triple elem[maxTerms];
}SparseMatrix;
SparseMatrix.cpp
#include"SparseMatrix.h"
#include<cstdlib>
void createSMatrix(SparseMatrix &A)
{
//从键盘输入建立一批三元组,建立稀疏矩阵的三元组表示。
//约定输入行号为-1结束。
int i, j, k, r, c;
DataType val;
printf("请输入矩阵的行数和列数:(空格隔开)\n"); scanf("%d %d", &r, &c);
A.Rows = r; A.Cols = c; A.Terms = 0;
printf("输入三元组:"); scanf("%d %d %d", &r, &c,&val);
while (r != -1)
{
if (A.Terms == 0) //三元表中暂无元素
{
A.elem[A.Terms].row = r;
A.elem[A.Terms].col = c;
A.elem[A.Terms++].value = val;
}
else
{
for (i == A.Terms - 1; i > 0; i--) //从后向前寻找适合插入的行
{
if (A.elem[i].row > r)
A.elem[i + 1] = A.elem[i];
else
break;
}
if (A.elem[i].row < r) //当前行号小要插入的行
{
A.elem[i + 1].row = r;
A.elem[i + 1].col = c;
A.elem[i + 1].value = val;
}
else //当前行号等于要插入的行
{
for (j = i; j >= 0; j--) //从后向前寻到适合插入的列
{
if (A.elem[j].col > col)
A.elem[j + 1] = A.elem[j];
else
break;
}
A.elem[j + 1].row = r;
A.elem[j + 1].col = c;
A.elem[j + 1].value = val;
}
A.Terms++;
}
printf("请输入三元组:");
scanf("%d %d %d", &r, &c, &val);
}
}
void printSMatrix(SparseMatrix & A)
{
printf("矩阵行数为%d 列数为%d,非零元为%d\n", A.Rows, A.Cols, A.Terms);
printf("三元组表依此为:\n");
for (int i = 0; i < A.Terms; i++)
printf("%3d,%3d,%5d\n", A.elem[i].row, A.elem[i].col, A.elem[i].value);
}
void Transpose(SparseMatrix &A, SparseMatrix &B) //转置
{
int CurrentB, k, i;
B.Rows = A.Cols; B.Cols = A.Rows; A.Terms = B.Terms;
if (A.Terms > 0)
{
CurrentB = 0; //转置三元组表存放指针
for (k = 0; k < A.Cols; k++) //将所有列号处理一遍
{
for (i = 0; i < A.Terms; i++) //在数组中找到列号为k的三元组
{
if (A.elem[i].col == k) //第i个三元组中元素列号为k
{
B.elem[CurrentB].row = k;
B.elem[CurrentB].col = A.elem[i].row;
B.elem[CurrentB].value = A.elem[i].value;
CurrentB++; //存放指针加一
}
}
}
}
}
void FastTranspos(SparseMatrix &A, SparseMatrix &B) //借助辅助数组的转置
{
int *rowSize = (int*)malloc(A.Cols * sizeof(int));
int *rowStart = (int*)malloc(A.Cols * sizeof(int));
int i, j;
B.Rows = A.Cols;
B.Cols = A.Rows;
B.Terms = A.Terms;
if (A.Terms > 0)
{
for (i = 0; i < A.Cols; i++) rowSize[i] = 0; //统计各列非零元素的个数
for (i = 0; i < A.Terms; i++) rowSize[A.elem[i].col]++;
rowStart[0] = 0; //计算转置后各行开始位置
for (i = 1; i < A.Cols; i++) rowStart[i] = rowStart[i - 1] + rowSize[i - 1];
for (i = 0; i < A.Terms; i++)
{
j = rowStart[A.elem[i].col];
B.elem[j].row = A.elem[i].col;
B.elem[j].col = A.elem[i].row;
B.elem[j].value = A.elem[i].value;
rowStart[A.elem[i].col]++;
}
}
free(rowSize);
free(rowStart);
}
/*矩阵的相加 A+B = C */
bool AddMatrix(SparseMatrix &A, SparseMatrix &B, SparseMatrix &C)
{
Triple temp; DataType sum;
if (A.Rows != B.Rows || A.Cols != B.Cols) return false;
C.Rows = A.Rows; C.Cols = A.Cols;
int i, j, k;
i = j = k = 0;
while (i < A.Terms || j < B.Terms)
{
if (k > maxTerms) return false;
if (A.elem[i].row < B.elem[j].row)
C.elem[k++] = A.elem[i++];
else if (A.elem[i] > B.elem[j])
C.elem[k++] = B.elem[j++];
else
{
if (A.elem[i].col < B.elem[i])
C.elem[k++] = A.elem[i++];
else if (A.elem[i] > B.elem[j])
C.elem[k++] = B.elem[j++];
else
{
sum = A.elem[i].value + B.elem[j].value;
if (sum)
{
temp.row = A.elem[i].row;
temp.col = A.elem[j].col;
temp.value = sum;
C.elem[k++] = temp;
}
i++; j++;
}
}
}
C.Terms = k;
}
/*矩阵的乘法A*B = C */
bool MultiMatix(SparseMatrix &A, SparseMatrix &B, SparseMatrix &C)
{
if (A.Cols != B.Rows) return false; //矩阵相乘的条件
int i, j, ra, ca, cb, current, k;
int *rowSize = (int*)malloc(B.Rows * sizeof(int)); //矩阵B各行非零元素的个数
int *rowStart = (int*)malloc((B.Rows + 1) * sizeof(int)); //矩阵B各行的起始位置
DataType *temp = (DataType*)malloc(B.Cols * sizeof(DataType)); //存放矩阵C一行的结果
for (i = 0; i < B.Rows; i++) rowSize[i] = 0;
for (i = 0; i < B.Terms; i++) rowSize[B.elem[i].row]++; //计算非零元素个素
rowStart[0] = 0; //计算每行的起始位置
for (i = 0; i < B.Terms; i++) rowStart[i] = rowStart[i - 1] + rowSize[i - 1];
current = 0, k = -1; //A的扫描指针,C的结果存放指针
while (current < A.Terms) //处理A的每个三元组
{
for (j = 0; j < B.Cols; j++) temp[j] = 0; //temp初始化
ra = A.elem[current].row;
while (current < A.Terms && A.elem[current].row == ra) //这个循环用来计算A中当前行,
{ //与B中各列的结果,一列一个结果,累加存入
//temp数组
ca = A.elem[current].col; //ca为A中当前行的列号
for (i = rowStart[ca]; i < rowStart[ca + 1]; i++) //取B中所有行号为ca的元素
{
cb = B.elem[i].col; //B中相乘元素的列号
temp[cb] = temp[cb] + A.elem[current].value*B.elem[i].value;
} //A[current][ca] 与B[ca][cb]相乘
current++;
}
for (i = 0; i < B.Cols; i++) //将temp中非零元素存入C中
{
if ( temp[i] != 0)
{
k++;
C.elem[k].col = ra;
C.elem[k].col = i;
C.elem[k].value = temp[i];
}
}
}
C.Rows = A.Rows;
C.Cols = B.Cols;
C.Terms = k + 1;
free(rowSize);
free(rowStart);
free(temp);
}