陣列12——稀疏矩陣的壓縮儲存2——稀疏矩陣的相加
阿新 • • 發佈:2018-12-22
設有兩個4*4的稀疏矩陣A和B,相加得到C,如圖所示,請編寫演算法,要求利用三元組表示法實現兩個稀疏矩陣的相加,並用矩陣形式輸出結果。
【分析】
先比較兩個稀疏矩陣的 先比較兩個稀疏矩陣A和B的行號,如果行號相等,則比較列號;如果行號與列號都相等,則將對應的元素值相加,並將下標m與n下標都加1比較下一個元素;如果行號相等,列號不相等,則將列號較小的矩陣的元素賦給矩陣C,並將列號小的下標繼續比較下一個元素;如果行號與列號都不相等,則將行號較小的矩陣的元素賦給C,並將行號小的下標比較下一個元素。
將兩個矩陣中對應元素相加,需要考慮以下3種情況:
(1)A中的元素aij≠0且B中的元素bij≠0,但是結果可為零,若結果為零則不儲存該元素如果結果不為零,則將結果儲存到C中。
(2)A中的第(i,j)個位置存在非零元素aij,而B中不存在非零,則只需要將該值賦給C。
(3)B中的第(i打個位置存在非零元素bij,而A中不存在非零元素,則只需要將該值賦給C。
為了將結果以矩陣形式輸出,可以先將一個二維陣列全部元素初始化為0,然後確定每一個非零元素的行號和列號,將該非零元素存入到對應位置即可,最後輸’出該二維陣列。
TriSeqMatrix.h
#define MaxSize 200 typedef struct /*三元組型別定義*/ { int i; /*非零元素的行號*/ int j; /*非零元素的列號*/ DataType e; }Triple; typedef struct /*矩陣型別定義*/ { Triple data[MaxSize]; int m; /*矩陣的行數*/ int n; /*矩陣的列數*/ int len; /*矩陣中非零元素的個數*/ }TriSeqMatrix; int CreateMatrix(TriSeqMatrix *M) /*建立稀疏矩陣(按照行優先順序輸入非零元素值)*/ { int i,m,n; DataType e; int flag; printf("請輸入稀疏矩陣的行數、列數及非零元素個數:"); scanf("%d,%d,%d",&M->m,&M->n,&M->len); if(M->len>MaxSize) return 0; for(i=0;i<M->len;i++) { do { printf("請按行序順序輸入第%d個非零元素所在的行(0~%d),列(0~%d),元素值:",i+1,M->m-1,M->n-1); scanf("%d,%d,%d",&m,&n,&e); flag=0; /*初始化標誌位*/ if(m<0||m>M->m||n<0||n>M->n) /*如果行號或列號正確,標誌位為1*/ flag=1; /*若輸入的順序正確,則標誌位為1*/ if(i>0&&m<M->data[i-1].i||m==M->data[i-1].i&&n<=M->data[i-1].j) flag=1; }while(flag); M->data[i].i=m; M->data[i].j=n; M->data[i].e=e; } return 1; } void CopyMatrix(TriSeqMatrix M,TriSeqMatrix *N) /*由稀疏矩陣M複製得到另一個副本N*/ { int i; N->len=M.len; /*修改稀疏矩陣N的非零元素的個數*/ N->m=M.m; /*修改稀疏矩陣N的行數*/ N->n=M.n; /*修改稀疏矩陣N的列數*/ for(i=0;i<M.len;i++) /*把M中非零元素的行號、列號及元素值依次賦值給N的行號、列號及元素值*/ { N->data[i].i=M.data[i].i; N->data[i].j=M.data[i].j; N->data[i].e=M.data[i].e; } } void TransposeMatrix(TriSeqMatrix M,TriSeqMatrix *N) /*稀疏矩陣的轉置*/ { int i,k,col; N->m=M.n; N->n=M.m; N->len=M.len; if(N->len) { k=0; for(col=0;col<M.n;col++) /*按照列號掃描三元組順序表*/ for(i=0;i<M.len;i++) if(M.data[i].j==col) /*如果元素的列號是當前列,則進行轉置*/ { N->data[k].i=M.data[i].j; N->data[k].j=M.data[i].i; N->data[k].e=M.data[i].e; k++; } } } void DestroyMatrix(TriSeqMatrix *M) /*銷燬稀疏矩陣*/ { M->m=M->n=M->len=0; }
main.cpp
#include<stdlib.h> #include<stdio.h> #include<malloc.h> #include<iostream> #include<iomanip> using namespace std; typedef int DataType; #include"TriSeqMatrix.h" int AddMatrix(TriSeqMatrix A, TriSeqMatrix B, TriSeqMatrix *C); void PrintMatrix(TriSeqMatrix M); void PrintMatrix2(TriSeqMatrix M); int CreateMatrix(TriSeqMatrix *M); int CompareElement(int a, int b); void main() { TriSeqMatrix M, N, Q; CreateMatrix(&M); PrintMatrix2(M); CreateMatrix(&N); PrintMatrix2(N); AddMatrix(M, N, &Q); PrintMatrix(Q); PrintMatrix2(Q); system("pause"); } void PrintMatrix(TriSeqMatrix M) /*輸出稀疏矩陣*/ { int i; cout << "稀疏矩陣是" << M.m << "行×" << M.n << "列,共" << M.len << "個非零元素" << endl; cout << "行 列 元素值" << endl; for (i = 0; i < M.len; i++) cout << setw(2) << M.data[i].i << setw(6) << M.data[i].j << setw(8) << M.data[i].e << endl; } void PrintMatrix2(TriSeqMatrix M) /*按矩陣樣式輸出稀疏矩陣*/ { int k, i, j; DataType a[MaxSize][MaxSize]; for (i = 0; i < M.m; i++)//初始化陣列a,全部元素置為0 for (j = 0; j < M.n; j++) a[i][j] = 0; for (k = 0; k < M.len; k++)//將非0元素存入陣列a { if (M.data[k].e != 0) { i = M.data[k].i; j = M.data[k].j; a[i][j] = M.data[k].e; } } cout << "稀疏矩陣(按矩陣形式輸出):" << endl; for (i = 0; i < M.m; i++)//按矩陣形式輸出陣列a中的元素 { for (j = 0; j < M.n; j++) cout << setw(4) << a[i][j]; cout << endl; } } int AddMatrix(TriSeqMatrix A, TriSeqMatrix B, TriSeqMatrix *C) /*將兩個矩陣A和B對應的元素值相加,得到另一個稀疏矩陣C*/ { int m = 0, n = 0, k = -1; if (A.m != B.m || A.n != B.n) /*如果兩個矩陣的行數與列數不相等,則不能夠進行相加運算*/ return 0; C->m = A.m; C->n = A.n; while (m < A.len&&n < B.len) { switch (CompareElement(A.data[m].i, B.data[n].i))/*比較兩個矩陣對應元素的行號*/ { case -1: C->data[++k] = A.data[m++]; /*將矩陣A,即行號小的元素賦值給C*/ break; case 0: /*如果矩陣A和B的行號相等,則比較列號*/ switch (CompareElement(A.data[m].j, B.data[n].j)) { case -1: /*如果A的列號小於B的列號,則將矩陣A的元素賦值給C*/ C->data[++k] = A.data[m++]; break; case 0: /*如果A和B的行號、列號均相等,則將兩元素相加,存入C*/ C->data[++k] = A.data[m++]; C->data[k].e += B.data[n++].e; if (C->data[k].e == 0) /*如果兩個元素的和為0,則不儲存*/ k--; break; case 1: /*如果A的列號大於B的列號,則將矩陣B的元素賦值給C*/ C->data[++k] = B.data[n++]; } break; case 1: /*如果A的行號大於B的行號,則將矩陣B的元素賦值給C*/ C->data[++k] = B.data[n++]; } } while (m < A.len) /*如果矩陣A的元素還沒處理完畢,則將A中的元素賦值給C*/ C->data[++k] = A.data[m++]; while (n < B.len) /*如果矩陣B的元素還沒處理完畢,則將B中的元素賦值給C*/ C->data[++k] = B.data[n++]; C->len = k + 1; /*修改非零元素的個數*/ if (k > MaxSize) return 0; return 1; } int CompareElement(int a, int b) /*比較兩個矩陣的元素值大小。前者小於後者,返回-1;相等,返回0;大於,返回1*/ { if (a < b) return -1; if (a == b) return 0; return 1; }
結果: