稀疏矩阵操作(三元组表示法)

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #define OK 1
  4. #define ERROR 0
  5. #define TRUE 1
  6. #define FALSE 0
  7. #define MAXSIZE 100
  8. typedef int Status;
  9. typedef float ElemType;
  10. typedef struct{//三元组结构
  11. int i, j;//非零元素行下标和列下标
  12. ElemType e;//非零元素值
  13. }Triple;
  14. typedef struct{
  15. Triple data[MAXSIZE + 1];//非零元三元组表,data[0]不用
  16. int mu, nu, tu;//矩阵的行数、列数和非零元素个数
  17. }TSMatrix;
  18. TSMatrix NewMatrix(int m, int n);
  19. //新建一个三元组表示的稀疏矩阵
  20. Status InsertElem(TSMatrix *M, int row, int col, ElemType e);
  21. //在三元组表示的稀疏矩阵M,第 row 行,第 col 列位置插入元素e
  22. //插入成功,返回OK,否则返回ERROR
  23. Status FindElem(const TSMatrix *M, int row, int col, ElemType *e);
  24. //查找三元组表示的稀疏矩阵M中,第 row 行,第 col列元素,若不为0,
  25. //则用e返回其值,并返回TRUE,否则返回FALSE
  26. Status TransposeSMatrix(const TSMatrix *M, TSMatrix *T);
  27. //采用三元组表存储表示,求稀疏矩阵M的转置矩阵T
  28. Status FastTransposeSMatrix(const TSMatrix *M, TSMatrix *T);
  29. //利用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T
  30. Status MultSMatrix(const TSMatrix *M, const TSMatrix *T, TSMatrix *Q);
  31. //稀疏矩阵的乘法,如果符合乘法规则,Q返回M*T结果,并返回OK,否则返回ERROR
  32. void PrintSMatrix(const TSMatrix *M);
  33. //打印稀疏矩阵所有元素
  34. int main()
  35. {
  36. TSMatrix M = NewMatrix(3, 4);
  37. TSMatrix T;
  38. TSMatrix Q;
  39. InsertElem(&M, 3, 2, 3.65);
  40. InsertElem(&M, 2, 2, 2.31);
  41. printf("\nM:");
  42. PrintSMatrix(&M);
  43. FastTransposeSMatrix(&M, &T);
  44. printf("\nT(Transpose of M):");
  45. PrintSMatrix(&T);
  46. MultSMatrix(&M, &T, &Q);
  47. printf("\nM*T=");
  48. PrintSMatrix(&Q);
  49. return 0;
  50. }
  51. TSMatrix NewMatrix(int m, int n){
  52. //新建一个三元组表示的稀疏矩阵
  53. TSMatrix M;
  54. M.mu = m;
  55. M.nu = n;
  56. M.tu = 0;
  57. return M;
  58. }
  59. Status InsertElem(TSMatrix *M, int row, int col, ElemType e){
  60. //在三元组表示的稀疏矩阵M,第 row 行,第 col 列位置插入元素e
  61. //插入成功,返回OK,否则返回ERROR
  62. int i, t, p;
  63. if (M->tu >= MAXSIZE){//当前三元组表已满
  64. printf("\nError:There is no space in the matrix;\n");
  65. return ERROR;
  66. }
  67. if (row>M->mu || col>M->nu || row<1 || col<1){//插入位置越界,不在1~mu或1~nu之间
  68. printf("\nError:Insert position is beyond the arrange.\n");
  69. return ERROR;
  70. }
  71. p = 1;//标志新元素应该插入的位置
  72. if (M->tu == 0){//插入前矩阵M没有非零元素
  73. M->data[p].i = row;
  74. M->data[p].j = col;
  75. M->data[p].e = e;
  76. M->tu++;
  77. return OK;
  78. }
  79. for (t = 1; t <= M->tu; t++)//寻找合适的插入位置
  80. if ((row >= M->data[t].i) && (col >= M->data[t].j))
  81. p++;
  82. if (row == M->data[t - 1].i && col == M->data[t - 1].j){//插入前,该元素已经存在
  83. M->data[t - 1].e = e;
  84. return OK;
  85. }
  86. for (i = M->tu; i >= p; i--){//移动p之后的元素
  87. M->data[i + 1].i = M->data[i].i;
  88. M->data[i + 1].j = M->data[i].j;
  89. M->data[i + 1].e = M->data[i].e;
  90. }
  91. //插入新元素
  92. M->data[p].i = row;
  93. M->data[p].j = col;
  94. M->data[p].e = e;
  95. M->tu++;
  96. return OK;
  97. }
  98. Status FindElem(const TSMatrix *M, int row, int col, ElemType *e){
  99. //查找三元组表示的稀疏矩阵M中,第 row 行,第 col列元素,若不为0,
  100. //则用e返回其值,并返回TRUE,否则返回FALSE
  101. int p;
  102. for (p = 1; p <= M->tu; p++)
  103. if (M->data[p].i == row&&M->data[p].j == col){
  104. *e = M->data[p].e;
  105. return TRUE;
  106. }
  107. return FALSE;
  108. }
  109. Status TransposeSMatrix(const TSMatrix *M, TSMatrix *T){
  110. //采用三元组表存储表示,求稀疏矩阵M的转置矩阵T
  111. int col, p, q;
  112. T->mu = M->nu; T->nu = M->mu; T->tu = M->tu;
  113. if (T->tu){
  114. q = 1;
  115. for (col = 1; col <= M->mu; col++)
  116. for (p = 1; p <= M->tu; p++)
  117. if (M->data[p].j == col){
  118. T->data[q].i = M->data[p].j;
  119. T->data[q].j = M->data[p].i;
  120. T->data[q].e = M->data[p].e;
  121. q++;
  122. }
  123. }
  124. return OK;
  125. }
  126. Status FastTransposeSMatrix(const TSMatrix *M, TSMatrix *T){
  127. //利用三元组顺序表存储表示,求稀疏矩阵M的转置矩阵T
  128. int col, t, p, q, *num, *cpot;
  129. T->mu = M->nu; T->nu = M->mu; T->tu = M->tu;
  130. if (T->tu){
  131. num = (int *)malloc(sizeof(int)*M->tu);
  132. cpot = (int *)malloc(sizeof(int)*M->tu);
  133. if (!(num&&cpot)){
  134. printf("Apply for memory error.\n");
  135. exit(0);
  136. }
  137. for (col = 1; col <= M->nu; col++) num[col] = 0;
  138. //求M中每一列含有非零元素的个数
  139. for (t = 1; t <= M->tu; t++) ++num[M->data[t].j];
  140. cpot[1] = 1;
  141. //求第col列中第一个非零元素在b.data中的序号
  142. for (col = 2; col <= M->nu; col++)
  143. cpot[col] = cpot[col - 1] + num[col - 1];
  144. for (p = 1; p <= M->tu; p++){
  145. col = M->data[p].j; q = cpot[col];
  146. T->data[q].i = M->data[p].j;
  147. T->data[q].j = M->data[p].i;
  148. T->data[q].e = M->data[q].e;
  149. ++cpot[col];
  150. }//for
  151. }//if
  152. return OK;
  153. }
  154. Status MultSMatrix(const TSMatrix *M, const TSMatrix *T, TSMatrix *Q){
  155. //稀疏矩阵的乘法,如果符合乘法规则,Q返回M*T结果,并返回OK,否则返回ERROR
  156. int i, j, k, p;
  157. ElemType m, t, s;
  158. if (M->nu != T->mu){
  159. printf("Sorry,these two matrice can't multiply.\n");
  160. return ERROR;
  161. }
  162. Q->mu = M->mu; Q->nu = T->nu; Q->tu = 0;
  163. p = 1;
  164. for (i = 1; i <= Q->mu; i++){
  165. for (j = 1; j <= Q->nu; j++){
  166. s = 0;
  167. for (k = 1; k <= M->nu; k++){
  168. if (FALSE == FindElem(M, i, k, &m))
  169. continue;
  170. if (FALSE == FindElem(T, k, j, &t))
  171. continue;
  172. s += m*t;
  173. }
  174. if (s != 0){//Q[i][j]非零
  175. Q->data[p].i = i;
  176. Q->data[p].j = j;
  177. Q->data[p].e = s;
  178. p++;
  179. Q->tu++;
  180. }
  181. }
  182. }
  183. return OK;
  184. }
  185. void PrintSMatrix(const TSMatrix *M){
  186. //打印稀疏矩阵所有元素
  187. int i, j, p = 1;
  188. printf("\nsize:%d × %d\n", M->mu, M->nu);
  189. if (!M->tu){//0矩阵
  190. printf("%g\n", 0.0);
  191. return;
  192. }
  193. for (i = 1; i <= M->mu; i++){
  194. for (j = 1; j <= M->nu; j++){
  195. if (i == M->data[p].i && j == M->data[p].j){
  196. printf("%g\t", M->data[p].e);
  197. p++;
  198. }
  199. else{
  200. printf("%g\t", 0.0);
  201. }
  202. }
  203. printf("\n");
  204. }
  205. printf("\n");
  206. }





posted @ 2015-07-07 12:52  Lucas_1993  阅读(2007)  评论(0编辑  收藏  举报