稀疏矩阵的一些运算C实现(转)

#include <iostream>
#include <iomanip>
using namespace std;


const int MAXSIZE = 100; //定义非零元素的最多个数
const int MAXROW = 10; //定义数组行数的最大值
const int SIZENUM = 10;


typedef struct //定义三元组元素
{
int r, c; //矩阵的行号和列号
int v; //矩阵元素值
}Triple;


typedef struct //定义普通三元组对象
{
Triple data[MAXSIZE+1];
int rows, cols, nzeroNums; //行数、列数、非零元素个数
}TSMatrix;


typedef struct //定义行逻辑链接的顺序表
{
Triple data[MAXSIZE+2]; //非0元三元组表
int rpos[MAXROW+1]; //各行第一个非零元素的位置表
int rows, cols, nzeroNums; //行数、列数、非零元素个数
}RLSMatrix;


//输入三元组矩阵
template <class T>
bool InputTSMatrix(T &M, int y)
{
cout << "输入矩阵的行数、列数和非零元素个数: ";
cin >> M.rows >> M.cols >> M.nzeroNums;
cout << "请输入非零元素对应的行号、列号和相应的元素值: " << endl;
for (int i = 1; i <= M.nzeroNums; i++)
{
cin >> M.data[i].r >> M.data[i].c >> M.data[i].v;
}
return true;
}


//输出矩阵,按标准格式输出
template <class T>
bool OutputSMatrix(T M)
{
int i, j, k = 1;
for (i = 0; i < M.rows; i++)
{
for (j = 0; j < M.cols; j++)
{
if ((M.data[k].r-1) == i && (M.data[k].c-1) == j)
{
cout << setw(4) << M.data[k].v;
k++;
}
else
cout << setw(4) << "0";
}//end_j
cout << endl;
}//end_i
return true;
}


//求稀疏矩阵的转置
int TranSMatrix()
{
TSMatrix M, T;
InputTSMatrix(M, 0);
int col, p, q = 1;
T.rows = M.cols;
T.cols = M.rows;
T.nzeroNums = M.nzeroNums;
if (T.nzeroNums)
{
for (col = 1; col <= M.cols; col++)
{
for (p = 1; p <= M.nzeroNums; p++)
{
if (M.data[p].c == col)
{
T.data[q].r = M.data[p].c;
T.data[q].c = M.data[p].r;
T.data[q].v = M.data[p].v;
++q;
}
}//end_p
}//end_col
}//end_if
cout << "运用普通转置算法, 输入矩阵的转置矩阵为: " << endl;
OutputSMatrix(T);
return 1;
}


//稀疏矩阵的快速转置
int FastTranMat()
{
TSMatrix M, T;
int num[MAXROW+1]; //表示矩阵M中第col列非零元素的个数
int cpot[MAXROW+1]; //表示矩阵M中第col列第一个非0元素在b.data中的位置
int p, q, col, t;
InputTSMatrix(M, 0); //输入稀疏矩阵
T.rows = M.cols;
T.cols = M.rows;
T.nzeroNums = M.nzeroNums;
if (T.nzeroNums)
{
for (col = 1; col <= M.cols; col++)//M中各列元素初始化
{
num[col] = 0;
}
for (t = 1; t <= M.nzeroNums; t++)
{
++num[M.data[t].c]; //求M中每一列非零元个数
}
//求第col列第一个非零元在b.data中的序号
cpot[1] = 1;
for (col = 2; col <= M.cols; col++)
{
cpot[col] = cpot[col-1] + num[col-1];
}
for (p = 1; p <= M.nzeroNums; p++)
{
col = M.data[p].c; //稀疏矩阵M中每个元素对应的列号
q = cpot[col]; //稀疏矩阵M中第一个非零元素位置
T.data[q].r = M.data[p].c;
T.data[q].c = M.data[p].r;
T.data[q].v = M.data[p].v;
++cpot[col];
}//end_for
}//end_if
cout << "运用快速算法,输入矩阵的转置为: " << endl;
OutputSMatrix(T);
return 1;
}


//求取稀疏矩阵每一行非零元个数
bool Count(RLSMatrix &M)
{
int row, p;
int num[MAXROW+1];
for (row = 1; row <= M.rows; row++)
{
num[row] = 0; //清零
}
for (p = 1; p <= M.nzeroNums; p++)
{
++num[M.data[p].r]; //统计M每一行非零元个数
}
M.rpos[1] = 1;
//M中每一行非零元的起始位置
for (row = 2; row <= M.rows; row++)
{
M.rpos[row] = M.rpos[row-1] + num[row-1];
}
return true;
}


//两个稀疏矩阵的乘法
bool MultSMatrix()
{
RLSMatrix M, N, Q; //构建三个带链接信息的三元组表示的数组
InputTSMatrix(M, 1); //用普通三元组形式输入数组
InputTSMatrix(N, 1);
Count(M);
Count(N);
if (M.cols != N.rows)
{
cout << "Error!";
return false;
}
//Q的初始化
Q.rows = M.rows;
Q.cols = N.cols;
Q.nzeroNums = 0;
int mrow, nrow, p, q, t, tp, qcol;
int ctemp[MAXROW+1]; //辅助数组
//如果Q是非零矩阵
if (M.nzeroNums * N.nzeroNums)
{
for (mrow = 1; mrow <= M.rows; mrow++)
{
//当前行各元素累加器清零
for (int x = 1; x <= N.cols; x++)
{
ctemp[x] = 0;
}//end_x
//当前行的首个非零元素在三元组中的位置为此行前所有非0元素加1
Q.rpos[mrow] = Q.nzeroNums + 1;
if (mrow < M.rows)
{
tp = M.rpos[mrow+1];
}
else
tp = M.nzeroNums + 1;
for (p = M.rpos[mrow]; p < tp; p++) //对当前行的每个非零元素操作
{
nrow = M.data[p].c; //在N中找到与M操作元素的c值相等的行值r
if (nrow < N.rows)
{
t = N.rpos[nrow+1];
}
else
t = N.nzeroNums + 1;
//对找出的行的每个非零元素进行操作
for (q = N.rpos[nrow]; q < t; q++)
{
qcol = N.data[q].c;
//将乘得到的对应值放在相应元素的累加器里面
ctemp[qcol] += M.data[p].v * N.data[q].v;
}
}//p_end_for

//对已经求出的累加器中的值压缩到Q中
for (qcol = 1; qcol <= Q.cols; qcol++)
{
if (ctemp[qcol])
{
if (++Q.nzeroNums > MAXSIZE)
{
cout << "Error!" << endl;
return 0;
}
Q.data[Q.nzeroNums].r = mrow;
Q.data[Q.nzeroNums].c = qcol;
Q.data[Q.nzeroNums].v = ctemp[qcol];
}
}//qcol_end_for
}//arow_end_for
}//end_if
cout << "两个稀疏矩阵相乘的结果为: ";
OutputSMatrix(Q);
return 1;
}


//两个稀疏矩阵的加法
int AddMatrix()
{
TSMatrix A, B, C;
int i = 1, j = 1, k = 1; //i, j, k分别用以保存A、B、C非零元素个数
int value = 0;
InputTSMatrix(A, 0);
InputTSMatrix(B, 0);
if (A.rows != B.rows || A.cols != B.cols)
{
cout << "两个稀疏矩阵的大小不等,不能相加!" << endl;
return 0;
}
if (A.rows == B.rows && A.cols == B.cols)
{
while (i <= A.nzeroNums && j <= B.nzeroNums)
{
if (A.data[i].r == B.data[j].r)
{
if (A.data[i].c < B.data[j].c)
{
C.data[k].r = A.data[i].r;
C.data[k].c = A.data[i].c;
C.data[k].v = A.data[i].v;
k++;
i++;
}
else if (A.data[i].c > B.data[j].c)
{
C.data[k].r = B.data[j].r;
C.data[k].c = B.data[j].c;
C.data[k].v = B.data[j].v;
k++;
j++;
}
else
{
value = A.data[i].v + B.data[j].v;
if (value != 0)
{
C.data[k].r = A.data[i].r;
C.data[k].c = A.data[i].c;
C.data[k].v = value;
k++;
}
i++;
j++;
}
}//end_if
else if (A.data[i].r < B.data[j].r)
{
C.data[k].r = A.data[i].r;
C.data[k].c = A.data[i].c;
C.data[k].v = A.data[i].v;
k++;
i++;
}
else
{
C.data[k].r = B.data[j].r;
C.data[k].c = B.data[j].c;
C.data[k].v = B.data[j].v;
k++;
j++;
}
//把剩余部分元素存入C中
if (i > A.nzeroNums && j <= B.nzeroNums)
{
for (; j <= B.nzeroNums; j++)
{
C.data[k].r = B.data[j].r;
C.data[k].c = B.data[j].c;
C.data[k].v = B.data[j].v;
k++;
}
}
if (i <= A.nzeroNums && j > B.nzeroNums)
{
for (; i <= A.nzeroNums; i++)
{
C.data[k].r = A.data[i].r;
C.data[k].c = A.data[i].c;
C.data[k].v = A.data[i].v;
k++;
}
}
}//end_while
C.rows = A.rows;
C.cols = A.cols;
C.nzeroNums = k-1;
cout << "输出两个稀疏矩阵的和: " << endl;
OutputSMatrix(C);
return 1;
}//end_if
else
return 0;
}


//两个稀疏矩阵的减法
int SubMatrix()
{
TSMatrix A, B, C;
int m = 1, n = 1, k = 1, temp;
InputTSMatrix(A, 0);
InputTSMatrix(B, 0);
C.rows = A.rows;
C.cols = A.cols;
C.nzeroNums = 0;
if (A.rows == B.rows && A.cols == B.cols)
{
while (m <= A.nzeroNums && n <= B.nzeroNums)
{
if (A.data[m].r == B.data[n].r)
{
if (A.data[m].c == B.data[n].c)
{
temp = A.data[m].v - B.data[n].v;
if (temp != 0)
{
C.data[k].r = A.data[m].r;
C.data[k].c = A.data[m].c;
C.data[k].v = temp;
k++;
}
m++;
n++;
}
else if (A.data[m].c < B.data[n].c)
{
C.data[k].r = A.data[m].r;
C.data[k].c = A.data[m].c;
C.data[k].v = A.data[m].v;
k++;
m++;
}
else
{
C.data[k].r = B.data[n].r;
C.data[k].c = B.data[n].c;
C.data[k].v = -B.data[n].v;
k++;
n++;
}
}
else if (A.data[m].r < B.data[n].r)
{
C.data[k].r = A.data[m].r;
C.data[k].c = A.data[m].c;;
C.data[k].v = A.data[m].v;
k++;
m++;
}
else
{
C.data[k].r = B.data[n].r;
C.data[k].c = B.data[n].c;
C.data[k].v = -B.data[n].v;
k++;
n++;
}
}//end_while
if (m <= A.nzeroNums)
{
for (; m <= A.nzeroNums; m++)
{
C.data[k].r = A.data[m].r;
C.data[k].c = A.data[m].c;
C.data[k].v = A.data[m].v;
k++;
}
}
if (n <= B.nzeroNums)
{
for (; n <= B.nzeroNums; n++)
{
C.data[k].r = B.data[n].r;
C.data[k].c = B.data[n].c;
C.data[k].v = -B.data[n].v;
k++;
}
}
C.nzeroNums = k-1;
cout << "两个稀疏矩阵的差为: ";
OutputSMatrix(C);
return 1;
} //end_if
else
{
cout << "两个稀疏矩阵的大小不同,不能相减! ";
return 0;
}
}


//得到矩阵元素M[i][j]的值
int value(TSMatrix M, int i, int j)
{
int k;
for (k = 1; k <= M.nzeroNums; k++)
{
if (M.data[k].r == i && M.data[k].c == j)
{
return M.data[k].v;
}
}
return 0;
}


//矩阵乘法的算法2
int MultMat()
{
TSMatrix A, B, C;
InputTSMatrix(A, 0);
InputTSMatrix(B, 0);
int i, j, k, temp = 0, p = 1;
if (A.cols != B.rows)
{
cout << "矩阵A的列数不等于矩阵B的行数不能相乘! ";
return 0;
}
else
{
for (i = 1; i <= A.rows; i++)
{
for (j = 1; j <= B.cols; j++)
{
temp = 0;
for (k = 1; k <= A.cols; k++)
{
temp += value(A, i, k) * value(B, k, j);
}
if (temp != 0)
{
C.data[p].r = i;
C.data[p].c = j;
C.data[p].v = temp;
p++;
}
}
}
C.rows = A.rows;
C.cols = B.cols;
C.nzeroNums = p-1;
OutputSMatrix(C);
return 1;
}
}


//计算矩阵的行列式, 通过递归算法来实现
int JsMatrix(int s[][MAXROW], int n)
{
int i, j, k, r, total = 0;
int b[SIZENUM][SIZENUM]; //b[N][N]用于存放在矩阵s[N][N]中元素s[0]的余之式

if (n == 1)
{
total = s[0][0];
}
else if (n == 2)
{
total = s[0][0] * s[1][1] - s[0][1] * s[1][0];
}
else
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n-1; j++)
{
for (k = 0; k < n-1; k++)
{
if (k >= i)
{
b[j][k] = s[j+1][k+1];
}
else
{
b[j][k] = s[j+1][k];
}
}//end_for_k
}//end_for_j
if (i % 2 == 0)
{
r = s[0][i] * JsMatrix(b, n-1); //递归调用
}
else
{
r = (-1) * s[0][i] * JsMatrix(b, n-1);
}
total += r;
}//end_for_i
}//end_else
return total;
}


//求原矩阵个元素对应的余之式, 存放在b[n][n]中,定义为float型
void N1Matrix(int s[][SIZENUM], float b[][SIZENUM], int n)
{
int i, j, k, l, m, g, a[SIZENUM][SIZENUM];
for (i = 0; i < n; i++)
{
m = i;
for (j = 0; j < n; j++)
{
g = j;
for (k = 0; k < n-1; k++)
{
for (l = 0; l < n-1; l++)
{
if (k >= m && l >= g)
{
a[k][l] = s[k+1][l+1];
}
else if (k < m && l >= g)
{
a[k][l] = s[k][l+1];
}
else if (k >= m && l < g)
{
a[k][l] = s[k+1][l];
}
else
{
a[k][l] = s[k][l];
}
}//end_for_l
}//end_for_k
b[i][j] = JsMatrix(a, n-1);
}//end_for_j
}//end_for_i
}


//稀疏矩阵求逆
void InverseMat()
{
TSMatrix M;
InputTSMatrix(M, 0);
int i, j, k, n = M.rows;
float temp;
int a[SIZENUM][SIZENUM];
float b[SIZENUM][SIZENUM], c[SIZENUM][SIZENUM];
for (i = 0; i < n; i++) //初始化矩阵a
{
for (j = 0; j < n; j++)
{
a[i][j] = 0;
}
}
for (i = 1; i <= M.nzeroNums; i++) //给矩阵a赋值
{
a[M.data[i].r-1][M.data[i].c-1] = M.data[i].v;
}
cout << "稀疏矩阵对应的普通矩阵为: ";
for (i = 0; i < n; i++) //打印原矩阵
{
for (j = 0; j < n; j++)
{
cout << setw(4) << a[i][j] << setw(4);
}
cout << endl;
}
k = JsMatrix(a, n);
cout << "矩阵的行列式值: |A| = " << k << endl;
if (k == 0)
{
cout << "行列式的值为0, 原矩阵无逆矩阵!" << endl;
}
else
{
N1Matrix(a, b, n); //调用函数,得到原矩阵各元素对应的余之式存放在数组b[n][n]中
//求代数余之式
cout << "普通矩阵各元素对应的代数余之式矩阵为: ";
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if ((i+j)%2 != 0 && b[i][j] != 0)
{
b[i][j] = -b[i][j];
}
cout << setw(4) << b[i][j] << setw(4);
}
cout << endl;
}//end_for_i


//对b[N][N]转置,此时b[n][n]存放的为原矩阵的伴随矩阵
for (i = 0; i < n; i++)
{
for (j = i+1; j < n; j++)
{
temp = b[i][j];
b[i][j] = b[j][i];
b[j][i] = temp;
}
}
cout << "伴随矩阵A*: " << endl;
for (i = 0; i < n; i++) //打印伴随矩阵A*
{
for (j = 0; j < n; j++)
{
cout << setw(4) << b[i][j] << setw(4);
}
cout << endl;
}
for (i = 0; i < n; i++) //求逆矩阵,此时c[n][n]中存放的是原矩阵的逆矩阵
{
for (j = 0; j < n; j++)
{
c[i][j] = b[i][j]/k;
}
}
cout << "逆矩阵(A*)/|A|: " << endl;
for (i = 0; i < n; i++) //打印逆矩阵
{
for (j = 0; j < n; j++)
{
cout << setw(6) << c[i][j] << setw(6);
}
cout << endl;
}
}//end_else
}


int main()
{
char c;
cout << setw(50) << "******欢迎使用稀疏矩阵的相关操作!******" << endl << endl;
cout.fill('*');
cout << setw(20) << '*';
cout << "请选择要进行的操作";
cout << setw(20) << '*' << endl;
cout << setw(6) << '*' << " 1: 稀疏矩阵的普通转置算法" << endl;
cout << setw(6) << '*' << " 2: 稀疏矩阵的快速转置算法" << endl;
cout << setw(6) << '*' << " 3: 稀疏矩阵的乘法的快速算法" << endl;
cout << setw(6) << '*' << " 4: 稀疏矩阵的乘法的经典算法" << endl;
cout << setw(6) << '*' << " 5: 稀疏矩阵的加法" << endl;
cout << setw(6) << '*' << " 6: 稀疏矩阵的减法" << endl;
cout << setw(6) << '*' << " 7: 求稀疏矩阵的逆" << endl;
cout << setw(6) << '*' << " 0: 退出程序" << endl;
cout.fill(' ');
c = getchar();
switch(c)
{
case '1':
TranSMatrix();
break;
case '2':
FastTranMat();
break;
case '3':
MultSMatrix();
break;
case '4':
MultMat();
break;
case '5':
AddMatrix();
break;
case '6':
SubMatrix();
break;
case '7':
InverseMat();
break;
case '0':
cout << "谢谢使用! 再见!" << endl;
break;
default:
cout << "错误命令!" << endl << endl;
break;
}
return 0;
}

原文地址:https://www.cnblogs.com/hjj-fighting/p/12794321.html