标签:cte 三元 star def list stat 定义 -- type
1 /****************************************************** 2 * * 3 * 文件夹: ▲05 数组和广义表\03 RowLinkSparseMatrix * 4 * * 5 * 文件名: RowLinkSparseMatrix.h * 6 * * 7 * 内 容: 行逻辑链接的顺序表(稀疏矩阵)相关操作列表 * 8 * * 9 ******************************************************/ 10 11 #ifndef ROWLINKSPARSEMATRIX_H 12 #define ROWLINKSPARSEMATRIX_H 13 14 #include <stdio.h> 15 #include <stdarg.h> //提供宏va_list、va_start、va_arg、va_end 16 #include "../../01 绪论/Status.h" //**▲01 绪论**// 17 #include "../../01 绪论/Scanf.c" //**▲01 绪论**// 18 19 /* 宏定义 */ 20 #define MAXSIZE 400 //假设非零元个数的最大值为400 21 #define MAXRC 20 //各行元素个数的最大值 22 23 /* 行逻辑链接的稀疏矩阵类型定义 */ 24 typedef int MElemType_RLSq; 25 typedef struct 26 { 27 int i, j; //该非零元的行下标和列下标 28 MElemType_RLSq e; 29 }Triple; 30 typedef struct 31 { 32 Triple data[MAXSIZE+1]; //非零元三元组表data[0]未用 33 int rpos[MAXRC+1]; //各行第一个非零元在三元组表中的位置表 34 int mu, nu, tu; //矩阵的行数、列数和非零元个数 35 }RLSMatrix; 36 37 /* 行逻辑链接的顺序表(稀疏矩阵)基础操作 */ 38 Status CreateSMatrix_RL(FILE *fp, int n, ...); 39 /*━━━━━━━━┓ 40 ┃(01)创建矩阵M。 ┃ 41 ┗━━━━━━━━*/ 42 43 void DestroySMatrix_RL(RLSMatrix *M); 44 /*━━━━━━━┓ 45 ┃(02)销毁矩阵。┃ 46 ┗━━━━━━━*/ 47 48 void PrintSMatrix_RL(RLSMatrix M); 49 /*━━━━━━━┓ 50 ┃(03)输出矩阵。┃ 51 ┗━━━━━━━*/ 52 53 void CopySMatrix_RL(RLSMatrix M, RLSMatrix *T); 54 /*━━━━━━━━┓ 55 ┃(04)矩阵的复制。┃ 56 ┗━━━━━━━━*/ 57 58 Status AddSMatri_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q); 59 /*━━━━━━━━┓ 60 ┃(05)Q = M + N。 ┃ 61 ┗━━━━━━━━*/ 62 63 Status SubSMatrix_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q); 64 /*━━━━━━━━┓ 65 ┃(06)Q = M - N。 ┃ 66 ┗━━━━━━━━*/ 67 68 Status MultSMatrix_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q); 69 /*━━━━━━━━━━━━┓ 70 ┃(07)算法5.3:Q = M * N。┃ 71 ┗━━━━━━━━━━━━*/ 72 73 void TransposeSMatrix_RL(RLSMatrix M, RLSMatrix *T); 74 /*━━━━━━━┓ 75 ┃(08)矩阵转置。┃ 76 ┗━━━━━━━*/ 77 78 void FastTransposeSMatrix_RL(RLSMatrix M, RLSMatrix *T); 79 /*━━━━━━━━━┓ 80 ┃(09)矩阵快速转置。┃ 81 ┗━━━━━━━━━*/ 82 83 #endif
1 /**************************************************** 2 * * 3 * 文件夹: ▲05 数组和广义表\03 RowLinkSparseMatrix * 4 * * 5 * 文件名: RowLinkSparseMatrix.c * 6 * * 7 * 算 法: 5.3 * 8 * * 9 ***************************************************/ 10 11 #ifndef ROWLINKSPARSEMATRIX_C 12 #define ROWLINKSPARSEMATRIX_C 13 14 #include "RowLinkSparseMatrix.h" //**▲05 数组和广义表**// 15 16 Status CreateSMatrix_RL(FILE *fp, int n, ...) 17 { 18 int count, k; 19 RLSMatrix *M; 20 21 if(n<1) 22 return ERROR; 23 24 va_list ap; 25 va_start(ap, n); 26 27 for(count=1; count<=n; count++) 28 { 29 M = va_arg(ap, RLSMatrix *); 30 31 for(k=0; k<=MAXRC; ++k) //初始化数组rpos 32 (*M).rpos[k] = 0; 33 34 Scanf(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu)); 35 36 for(k=1; k<=(*M).tu; k++) 37 { 38 Scanf(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e)); 39 40 if((*M).rpos[(*M).data[k].i]==0) //记录每行第一个非零元的位置 41 (*M).rpos[(*M).data[k].i] = k; //(只会在当前行有非零元的情况下记录) 42 } 43 44 for(k=(*M).mu; k>=1; --k) //处理那些没有非零元的行 45 { 46 if((*M).rpos[k]==0) 47 { 48 if(k==(*M).mu) //若最后一行无非零元,需特殊处理 49 (*M).rpos[k] = (*M).tu + 1; 50 else 51 (*M).rpos[k] = (*M).rpos[k+1]; 52 } 53 } 54 } 55 56 va_end(ap); 57 58 return OK; 59 } 60 61 void DestroySMatrix_RL(RLSMatrix *M) 62 { 63 int i; 64 65 M->mu = 0; 66 M->nu = 0; 67 M->tu = 0; 68 69 for(i=0; i<=MAXRC; ++i) 70 M->rpos[i] = 0; 71 } 72 73 void PrintSMatrix_RL(RLSMatrix M) 74 { 75 int r, c; 76 int k = 1; 77 78 for(r=1; r<=M.mu; ++r) 79 { 80 for(c=1; c<=M.nu; ++c) 81 { 82 if(r==M.data[k].i && c==M.data[k].j) 83 { 84 printf("%3d ", M.data[k].e); 85 k++; 86 } 87 else 88 printf(" 0 "); 89 } 90 printf("\n"); 91 } 92 93 printf("rpos = "); 94 for(k=1; k<=M.mu; ++k) 95 printf("%d ", M.rpos[k]); 96 printf("\n"); 97 } 98 99 void CopySMatrix_RL(RLSMatrix M, RLSMatrix *T) 100 { 101 (*T) = M; //结构可以直接复制 102 } 103 104 Status AddSMatri_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q) 105 { 106 int m, n, k; 107 int i; 108 109 if(M.mu!=N.mu || M.nu!=N.nu) 110 { 111 printf("两矩阵不能相加!!\n"); 112 return ERROR; 113 } 114 115 Q->mu = M.mu; 116 Q->nu = M.nu; 117 Q->tu = 0; 118 m = n = k = 1; 119 120 while(m<=M.tu && n<=N.tu) //依次遍历M与N的三元组 121 { 122 if(M.data[m].i<N.data[n].i) 123 { 124 Q->data[k] = M.data[m]; 125 m++; 126 } 127 else if(M.data[m].i>N.data[n].i) 128 { 129 Q->data[k] = N.data[n]; 130 n++; 131 } 132 else //M.data[m].i==N.data[n].i 133 { 134 if(M.data[m].j<N.data[n].j) 135 { 136 Q->data[k] = M.data[m]; 137 m++; 138 } 139 else if(M.data[m].j>N.data[n].j) 140 { 141 Q->data[k] = N.data[n]; 142 n++; 143 } 144 else //M.data[m].j==N.data[n].j 145 { 146 if(M.data[m].e+N.data[n].e) 147 { 148 Q->data[k].i = M.data[m].i; 149 Q->data[k].j = M.data[m].j; 150 Q->data[k].e = M.data[m].e+N.data[n].e; 151 m++; 152 n++; 153 } 154 else 155 { 156 m++; 157 n++; 158 continue; 159 } 160 } 161 } 162 163 k++; 164 Q->tu++; 165 } 166 167 while(m<=M.tu) 168 { 169 Q->data[k] = M.data[m]; 170 m++; 171 k++; 172 Q->tu++; 173 } 174 175 while(n<=N.tu) 176 { 177 Q->data[k] = N.data[n]; 178 n++; 179 k++; 180 Q->tu++; 181 } 182 183 for(i=0; i<=MAXRC; ++i) //初始化数组rpos 184 Q->rpos[i] = 0; 185 186 for(i=1; i<=Q->tu; ++i) 187 { 188 m = Q->data[i].i; //当前三元组中元素所在的行 189 if(Q->rpos[m]==0) //记录每行第一个非零元的位置 190 Q->rpos[m] = i; //(只会在当前行有非零元的情况下记录) 191 } 192 193 for(i=Q->mu; i>=1; --i) //处理那些没有非零元的行 194 { 195 if(Q->rpos[i]==0) 196 { 197 if(i==Q->mu) //若最后一行无非零元,需特殊处理 198 Q->rpos[i] = Q->tu + 1; 199 else 200 Q->rpos[i] = Q->rpos[i+1]; 201 } 202 } 203 204 return OK; 205 } 206 207 Status SubSMatrix_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q) 208 { 209 int m, n, k; 210 int i; 211 212 if(M.mu!=N.mu || M.nu!=N.nu) 213 { 214 printf("两矩阵不能相减!!\n"); 215 return ERROR; 216 } 217 218 Q->mu = M.mu; 219 Q->nu = M.nu; 220 Q->tu = 0; 221 m = n = k = 1; 222 223 while(m<=M.tu && n<=N.tu) 224 { 225 if(M.data[m].i<N.data[n].i) 226 { 227 Q->data[k] = M.data[m]; 228 m++; 229 } 230 else if(M.data[m].i>N.data[n].i) 231 { 232 Q->data[k].i = N.data[n].i; 233 Q->data[k].j = N.data[n].j; 234 Q->data[k].e = -N.data[n].e; 235 n++; 236 } 237 else //M.data[m].i==N.data[n].i 238 { 239 if(M.data[m].j<N.data[n].j) 240 { 241 Q->data[k] = M.data[m]; 242 m++; 243 } 244 else if(M.data[m].j>N.data[n].j) 245 { 246 Q->data[k].i = N.data[n].i; 247 Q->data[k].j = N.data[n].j; 248 Q->data[k].e = -N.data[n].e; 249 n++; 250 } 251 else //M.data[m].j==N.data[n].j 252 { 253 if(M.data[m].e-N.data[n].e) 254 { 255 Q->data[k].i = M.data[m].i; 256 Q->data[k].j = M.data[m].j; 257 Q->data[k].e = M.data[m].e-N.data[n].e; 258 m++; 259 n++; 260 } 261 else 262 { 263 m++; 264 n++; 265 continue; 266 } 267 } 268 } 269 270 k++; 271 Q->tu++; 272 } 273 274 while(m<=M.tu) 275 { 276 Q->data[k] = M.data[m]; 277 m++; 278 k++; 279 Q->tu++; 280 } 281 282 while(n<=N.tu) 283 { 284 Q->data[k].i = N.data[n].i; 285 Q->data[k].j = N.data[n].j; 286 Q->data[k].e = -N.data[n].e;; 287 n++; 288 k++; 289 Q->tu++; 290 } 291 292 for(i=0; i<=MAXRC; ++i) //初始化数组rpos 293 Q->rpos[i] = 0; 294 295 for(i=1; i<=Q->tu; ++i) 296 { 297 m = Q->data[i].i; //当前三元组中元素所在的行 298 if(Q->rpos[m]==0) //记录每行第一个非零元的位置 299 Q->rpos[m] = i; //(只会在当前行有非零元的情况下记录) 300 } 301 302 for(i=Q->mu; i>=1; --i) //处理那些没有非零元的行 303 { 304 if(Q->rpos[i]==0) 305 { 306 if(i==Q->mu) //若最后一行无非零元,需特殊处理 307 Q->rpos[i] = Q->tu + 1; 308 else 309 Q->rpos[i] = Q->rpos[i+1]; 310 } 311 } 312 313 return OK; 314 } 315 316 /*════╗ 317 ║ 算法5.3║ 318 ╚════*/ 319 Status MultSMatrix_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q) 320 { 321 int arow, brow, p, q, tp, tq, ccol; 322 int ctemp[N.nu+1]; //Q中各行元素值累加器,ctemp[0]不用 323 int i, m; 324 325 if(M.nu!=N.mu) //M列数等于N行数 326 { 327 printf("两矩阵不能相乘!!\n"); 328 return ERROR; 329 } 330 331 Q->mu = M.mu; //Q初始化 332 Q->nu = N.nu; 333 Q->tu = 0; 334 335 if(M.tu*N.tu) //Q是非零矩阵 336 { 337 for(arow=1; arow<=M.mu; ++arow) //处理M的每一行 338 { //arow为乘积元素在Q中的行号 339 for(i=0; i<=N.nu; ++i) //初始化Q中行元素值计数器 340 ctemp[i] = 0; 341 342 if(arow<M.mu) 343 tp = M.rpos[arow+1]; //tp指向M当前行的下一行第一个非零元位置 344 else 345 tp = M.tu + 1; 346 347 for(p=M.rpos[arow]; p<tp; ++p) //p从M当前行第一个非零元位置开始累加 348 { 349 brow = M.data[p].j; //对M当前行中每一个非零元,找到对应元在N中的行号 350 351 if(brow<N.mu) 352 tq = N.rpos[brow+1]; //tq指向N当前行的下一行第一个非零元位置 353 else 354 tq = N.tu + 1; 355 356 for(q=N.rpos[brow]; q<tq; ++q) //q从N当前行第一个非零元位置开始累加 357 { 358 ccol = N.data[q].j; //乘积元素在Q中的列号 359 ctemp[ccol] += M.data[p].e * N.data[q].e; 360 } 361 }//Q中第arow行元素已求出 362 363 for(ccol=1; ccol<=Q->nu; ++ccol) 364 { 365 if(ctemp[ccol]) //若Q中第arow行ccol列元素不为0 366 { 367 ++Q->tu; 368 if(Q->tu>MAXSIZE) //非零元个数超出限制 369 return ERROR; 370 Q->data[Q->tu].i = arow; 371 Q->data[Q->tu].j = ccol; 372 Q->data[Q->tu].e = ctemp[ccol]; 373 } 374 }//for(ccol) 375 }//for(arow) 376 }//if 377 378 for(i=0; i<=MAXRC; ++i) //初始化数组rpos 379 Q->rpos[i] = 0; 380 381 for(i=1; i<=Q->tu; ++i) 382 { 383 m = Q->data[i].i; //当前三元组中元素所在的行 384 if(Q->rpos[m]==0) //记录每行第一个非零元的位置 385 Q->rpos[m] = i; //(只会在当前行有非零元的情况下记录) 386 } 387 388 for(i=Q->mu; i>=1; --i) //处理那些没有非零元的行 389 { 390 if(Q->rpos[i]==0) 391 { 392 if(i==Q->mu) //若最后一行无非零元,需特殊处理 393 Q->rpos[i] = Q->tu + 1; 394 else 395 Q->rpos[i] = Q->rpos[i+1]; 396 } 397 } 398 399 return OK; 400 } 401 402 void TransposeSMatrix_RL(RLSMatrix M, RLSMatrix *T) 403 { 404 int p, q, col; 405 int i, m; 406 407 T->mu = M.nu; 408 T->nu = M.mu; 409 T->tu = M.tu; 410 411 for(i=0; i<=MAXRC; ++i) //初始化数组rpos 412 T->rpos[i] = 0; 413 414 if(T->tu) 415 { 416 q = 1; //q用于T中非零元计数 417 for(col=1; col<=M.nu; ++col) //col代表M的列,T的行 418 { 419 for(p=1; p<=M.tu; ++p) //p用于M中非零元计数 420 { 421 if(M.data[p].j==col) 422 { 423 T->data[q].i = M.data[p].j; //M的列变为T的行 424 T->data[q].j = M.data[p].i; //M的行变为T的列 425 T->data[q].e = M.data[p].e; //每个三元组值不变 426 427 if(T->rpos[col]==0) //记录每行第一个非零元的位置 428 T->rpos[col] = q; //(只会在当前行有非零元的情况下记录) 429 430 ++q; 431 } 432 } 433 } 434 } 435 436 for(i=T->mu; i>=1; --i) //处理那些没有非零元的行 437 { 438 if(T->rpos[i]==0) 439 { 440 if(i==T->mu) //若最后一行无非零元,需特殊处理 441 T->rpos[i] = T->tu + 1; 442 else 443 T->rpos[i] = T->rpos[i+1]; 444 } 445 } 446 } 447 448 void FastTransposeSMatrix_RL(RLSMatrix M, RLSMatrix *T) 449 { 450 int col, t, p, q; 451 int num[M.nu]; //num[col]表示M第col列中非零元的个数 452 int copt[M.nu]; //copt[col]表示M第col列第一个非零元在T->data中恰当的位置 453 int i, m; 454 455 T->mu = M.nu; 456 T->nu = M.mu; 457 T->tu = M.tu; 458 459 if(T->tu) 460 { 461 for(col=1; col<=M.nu; ++col) 462 num[col] = 0; //初始化数组num 463 464 for(t=1; t<=M.tu; ++t) //t遍历M中三元组 465 ++num[M.data[t].j]; //统计M中每列非零元个数 466 467 copt[1] = 1; 468 for(col=2; col<=M.nu; ++col) 469 copt[col] = copt[col-1] + num[col-1]; 470 471 for(p=1; p<=M.tu; ++p) //依次扫描M中的三元组 472 { 473 col = M.data[p].j; //col为M中第p个三元组中元素的列 474 q = copt[col]; //q为当前三元组元素在T中应放置的位置 475 T->data[q].i = M.data[p].j; 476 T->data[q].j = M.data[p].i; 477 T->data[q].e = M.data[p].e; 478 ++copt[col]; //再遇到此列元素时位置增一 479 } 480 } 481 482 for(i=0; i<=MAXRC; ++i) //初始化数组rpos 483 T->rpos[i] = 0; 484 485 for(i=1; i<=T->tu; ++i) 486 { 487 m = T->data[i].i; //当前三元组中元素所在的行 488 if(T->rpos[m]==0) //记录每行第一个非零元的位置 489 T->rpos[m] = i; //(只会在当前行有非零元的情况下记录) 490 } 491 492 for(i=T->mu; i>=1; --i) //处理那些没有非零元的行 493 { 494 if(T->rpos[i]==0) 495 { 496 if(i==T->mu) //若最后一行无非零元,需特殊处理 497 T->rpos[i] = T->tu + 1; 498 else 499 T->rpos[i] = T->rpos[i+1]; 500 } 501 } 502 } 503 504 #endif
标签:cte 三元 star def list stat 定义 -- type
原文地址:https://www.cnblogs.com/hongdoudou/p/12519546.html