数据结构之三元组顺序表实现稀疏矩阵运算(参考整理严蔚敏数据结构)

来源:互联网 发布:免费装修设计软件 编辑:程序博客网 时间:2024/06/16 00:00

#include<iostream>#include<iomanip>using namespace std;#define MAXSIZE 100typedef int ElemType;typedef struct Triple{int i;int j;ElemType e;}Triple;typedef struct TSMatrix{Triple Array[MAXSIZE + 1];//Array[0]放空int rows;int cols;int nums;//非零元的个数}TSMatrix;void CreateTS(TSMatrix &M){int t, m, n;ElemType e;bool k;cout << "请输入矩阵的行数,列数,非零元个数:";cin >> M.rows >> M.cols >> M.nums;M.Array[0].i = 0;for (t = 1; t<=M.nums; ++t){do{cout << "请按行序顺序输入第" << t << "个非零元素所在的行,列,元素值:";cin >> m >> n >> e;k = false;if (m<1 || m>M.rows || n<1 || n>M.cols)k = true;if (m < M.Array[t - 1].i || m == M.Array[t - 1].i&&n <= M.Array[t - 1].j)k = true;} while (k);M.Array[t].i = m;M.Array[t].j = n;M.Array[t].e = e;}}void DestroyTS(TSMatrix &M){M.rows = 0;M.cols = 0;M.nums = 0;}void CopyTS(TSMatrix M, TSMatrix &T){T = M;}void TransPose(TSMatrix M, TSMatrix &N){//一般转置矩阵int q;//B.Array的下标int p;//A.Array的下标int r;//A的列数的标记N.rows = M.cols; N.cols = M.rows; N.nums = M.nums;if (N.nums){//A中有非零元素q = 1;for (r = 1; r <= M.cols; r++){for (p = 1; p <= M.nums; p++){if (M.Array[p].j == r){N.Array[q].i = M.Array[p].j;N.Array[q].j = M.Array[p].i;N.Array[q].e = M.Array[p].e;q++;}}}}}void FastTransPose(TSMatrix M, TSMatrix &N){//快速转置矩阵int col, q, p, t;int num[20];//存放A中各列非零元的个数int cpot[20];//存放A中各列第一个非零元的位置N.rows = M.cols; N.cols = M.rows; N.nums = M.nums;if (N.nums){for (col = 1; col <= M.cols; col++)num[col] = 0;//num[col]A第col列非零元的个数for (t = 1; t <= M.nums; t++)++num[M.Array[t].j];cpot[1] = 1;//cpot[col]B中第col行第一个非零元在B中的位置for (col = 2; col <= M.cols; col++)cpot[col] = cpot[col-1] + num[col-1];for (p = 1; p <= M.nums; ++p){col = M.Array[p].j;q = cpot[col];//定位N.Array[q].i = M.Array[p].j;N.Array[q].j = M.Array[p].i;N.Array[q].e = M.Array[p].e;++cpot[col];//更新cpot数组}}}int comp(int c1, int c2){//辅助矩阵相加if (c1 < c2)return 1;else if (c1 > c2)return -1;elsereturn 0;}bool AddTS(TSMatrix A, TSMatrix B, TSMatrix &C){//矩阵相加Triple *Ap, *Ae, *Bp, *Be, *Ch, *Ce;if (A.rows != B.rows)return false;if (A.cols != B.cols)return false;C.rows = A.rows;C.cols = A.cols;Ap = &A.Array[1];// Ap的初值指向矩阵M的非零元素首地址Bp = &B.Array[1];// Bp的初值指向矩阵N的非零元素首地址Ae = &A.Array[A.nums]; //Ae指向矩阵M的非零元素尾地址Be = &B.Array[B.nums];//Be指向矩阵N的非零元素尾地址Ch = Ce = C.Array;// Ch,Ce的初值指向矩阵Q的非零元素首地址的前一地址while (Ap <= Ae&&Bp <= Be){Ce++;switch (comp(Ap->i,Bp->i))//比较行{case 1:*Ce = *Ap;Ap++;break;case 0:switch (comp(Ap->j, Bp->j))//行相等,比较列{case  1:*Ce = *Ap;Ap++;break;case  0:*Ce = *Ap;Ce->e += Bp->e;if (!Ce->e) // 元素值为0,不存入压缩矩阵Ce--;Ap++;Bp++;break;case -1:*Ce = *Bp;Bp++;}break;case -1:*Ce = *Bp;Bp++;}}if (Ap>Ae) // 矩阵M的元素全部处理完毕while (Bp <= Be){Ce++;*Ce = *Bp;Bp++;}if (Bp>Be) // 矩阵N的元素全部处理完毕while (Ap <= Ae){Ce++;*Ce = *Ap;Ap++;}C.nums = Ce - Ch; // 矩阵Q的非零元素个数return true;}void SubtractTS(TSMatrix A, TSMatrix B, TSMatrix &C){//矩阵相减int i;for (i = 1; i <= B.nums; ++i)B.Array[i].e *= -1;//将B中的非零元素的值变为其相反数AddTS(A, B, C);}bool MultiplyTS(TSMatrix A, TSMatrix B, TSMatrix &C){ //矩阵相乘int i, j, h = A.rows, l = B.cols, Cn = 0;//h,l为矩阵C的行,列值,Cn为矩阵C的非零元个数,初值为零ElemType *Ce;if (A.cols != B.rows)return false;C.rows = A.rows;C.cols = B.cols;Ce = new ElemType[h*l];for (i = 0; i<h*l; i++)*(Ce + i) = 0; //矩阵中所有元素初始化为零for (i = 1; i <= A.nums; i++)for (j = 1; j <= B.nums; j++)if (A.Array[i].j == B.Array[j].i)*(Ce + (A.Array[i].i - 1)*l + B.Array[j].j - 1) += (A.Array[i].e)*(B.Array[j].e);for (i = 1; i <= A.rows; i++){for (j = 1; j <= B.cols; j++){if (*(Ce + (i - 1)*l + j - 1)){Cn++;C.Array[Cn].e = *(Ce + (i - 1)*l + j - 1);C.Array[Cn].i = i;C.Array[Cn].j = j;}}}delete Ce;C.nums = Cn;return true;}void PrintTS(TSMatrix M){//打印矩阵int t;cout << "矩阵为:" << endl;cout << "元素的行数  " << "元素的列数  " << "内容" << endl;for (t = 1; t <= M.nums; ++t){cout << setw(8) << M.Array[t].i << setw(8) << M.Array[t].j<< setw(11) << M.Array[t].e << endl;}}int main(void){TSMatrix A,B,C;CreateTS(A);CreateTS(B);MultiplyTS(A, B, C);PrintTS(C);return(0);}

0 0
原创粉丝点击