zoukankan      html  css  js  c++  java
  • 稀疏矩阵操作(三元组表示法)

    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(" M:");
    42. PrintSMatrix(&M);
    43. FastTransposeSMatrix(&M, &T);
    44. printf(" T(Transpose of M):");
    45. PrintSMatrix(&T);
    46. MultSMatrix(&M, &T, &Q);
    47. printf(" M*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(" Error:There is no space in the matrix; ");
    65. return ERROR;
    66. }
    67. if (row>M->mu || col>M->nu || row<1 || col<1){//插入位置越界,不在1~mu或1~nu之间
    68. printf(" Error:Insert position is beyond the arrange. ");
    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. ");
    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. ");
    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(" size:%d × %d ", M->mu, M->nu);
    189. if (!M->tu){//0矩阵
    190. printf("%g ", 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 ", M->data[p].e);
    197. p++;
    198. }
    199. else{
    200. printf("%g ", 0.0);
    201. }
    202. }
    203. printf(" ");
    204. }
    205. printf(" ");
    206. }





  • 相关阅读:
    Hello iOS
    钝化程序、逻辑冻结、冻结程序的延续、瞬间转移
    对字符串操作的各种笔试题
    .NET各大平台数据列表控件绑定原理及比较(WebForm、Winform、WPF)
    多线程计算----pthread
    Xcode的Hello World(简单易懂)
    two sets of Qt binaries into the same process的解决办法
    微软新一代输入法框架 TSF
    Starting the application on Mac does not work(拷贝platforms到不同的位置,才能解决问题),还可设置DYLD_PRINT_LIBRARIES=1 观察动态库
    dddd
  • 原文地址:https://www.cnblogs.com/zhuzhenfeng/p/4626664.html
Copyright © 2011-2022 走看看