/* 稀疏矩陣 說明: 如果在矩陣中,多數的元素並沒有資料,稱此矩陣為稀疏矩陣(sparse matrix ), 由於矩陣在程式中常使用二維陣列表示,二維 陣列的大小與使用的記憶體空間成正比,如果多數的元素沒有資料 , 則會造成記憶體空間的浪費 , 為 此 , 必須設計稀疏矩陣 的陣列儲存方式 , 利用較少的記憶體空間儲存完整的矩陣資訊。 解法: 在這邊所介紹的方法較為簡單,陣列只儲存矩陣的行數、列數與有資料的索引位置及其值,在需要使用矩陣資料時,再透過程式運算 加以還原,例如若矩陣資料如下 ,其中0表示矩陣中該位置沒有資料: 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 6 0 0 0 0 9 0 0 0 0 0 0 0 12 0 這個矩陣是5X6矩陣,非零元素有4個,您要使用的陣列第一列記錄其列數、行數與非零元素個數: 5 6 4 陣列的第二列起,記錄其位置的列索引、行索引與儲存值: 1 1 3 2 3 6 3 2 9 4 4 12 所以原本要用30個元素儲存的矩陣資訊,現在只使用了15個元素來儲存,節省了不少記憶體的使用。 */ #include<stdio.h> #include<stdlib.h> int main(void){ int num[5][3] = {{5,6,4}, {1,1,3},{2,3,6},{3,2,9},{4,4,12}}; int i, j, k = 1; printf("sparse matrix: \n"); for(i = 0; i < 5; i++){ for(j = 0; j < 3; j++){ printf("%4d ", num[i][j]); } putchar('\n'); } printf("\nmatrix還原:\n"); for(i = 0; i < num[0][0]; i++){ for(j = 0; j < num[0][1]; j++){ if(k < num[0][2] && i == num[k][0] && j == num[k][1]){ printf("%4d ", num[k][2]); k++; }else{ printf("%4d", 0); } } putchar('\n'); } return 0; }
這個代碼貌似有點問題,運行結果就不貼了。
這是我寫的代碼:
/* 稀疏矩陣的簡單運算: 列序遞增轉置 一次定位快速轉置 201701031018 */ #include <stdio.h> #include <string.h> #define R 5 #define C 5 #define MAX 1000 #define MAXS 10 typedef struct { int row, col; //非零元素的行數,列數,值 int e; }Triple; typedef struct { Triple data[MAX+1]; int m, n, len; //稀疏矩陣的行數,列數,非零元素個數 }TSMatrix; //函數聲明 void print(TSMatrix A); //輸出三元組表 TSMatrix create(TSMatrix A, int a[R][C], TSMatrix B); //創建稀疏矩陣 void TranposeTSMatrix(TSMatrix A, TSMatrix *B); //列序遞增轉置 void FastTranposeTSMatrix(TSMatrix A, TSMatrix *B); //一次定位快速轉置 //輸出三元組表 void print(TSMatrix A) { int i; printf("row col e\n"); for(i = 1; i <= A.len; i++) { printf("%3d%4d%5d\n", A.data[i].row, A.data[i].col, A.data[i].e); } } //創建稀疏矩陣 TSMatrix create(TSMatrix A, int a[R][C], TSMatrix B) { int i, j; A.m = R; A.n = C; A.len = 0; printf("請輸入%d * %d的稀疏矩陣\n", A.m, A.n); for(i = 0, j = 0; i < A.m; i++, j = 0) { printf("第%d行矩陣元素為:", i+1); scanf("%d%d%d%d%d", &a[i][j], &a[i][j+1], &a[i][j+2], &a[i][j+3], &a[i][j+4]); // printf("\n"); } //輸入稀疏矩陣 printf("矩陣為:\n"); for(i=0; i<A.m;i++) { for(j=0; j<A.n;j++) { if(a[i][j] != 0) { A.len++; A.data[A.len].row = i+1; A.data[A.len].col = j+1; A.data[A.len].e = a[i][j]; } printf("%5d", a[i][j]); } printf("\n"); } //輸出矩陣,並統計非零元素個數A.len if(A.len < 7) { printf("稀疏矩陣共有%d個非零元素!\n", A.len); //輸出三元組表A printf("輸出三元組表 A 為:\n"); print(A); //輸出 按列序轉置后 的三元組表B printf("按列序轉置后三元組表 B 為:\n"); TranposeTSMatrix(A, &B); print(B); //輸出 快速轉置法 的三元組表B printf("按快速轉置法轉置后的三元組表 B 為:\n"); FastTranposeTSMatrix(A, &B); print(B); } else { printf("因為 A.len = %d, A.len >= %f ", A.len, (5*5*0.3)); printf("所以 你輸入的不是稀疏矩陣! \n"); // create(A, a, B); } //判斷是否為稀疏矩陣,若不是則重新輸入 printf("\n"); return A; } //列序遞增轉置 void TranposeTSMatrix(TSMatrix A, TSMatrix *B){ int i, j, k; B->m = A.m; B->n = A.n; B->len = A.len; if(B->len > 0) { j = 1; for(k = 1; k <= B->n; k++) { for(i = 1; i <= B->len; i++) { if(A.data[i].col == k) { B->data[j].row = A.data[i].col; B->data[j].col = A.data[i].row; B->data[j].e = A.data[i].e; j++; } } } } } //按列序遞增轉置 //一次定位快速轉置 void FastTranposeTSMatrix(TSMatrix A, TSMatrix *B){ int col, t, p, q; int num[MAXS], position[MAXS]; B->len = A.len; B->m = A.m; B->n = A.n; if(B->len) { for(col = 1; col <= A.n; col++) num[col] = 0; for(t = 1; t <= A.len; t++) num[A.data[t].col]++; position[1] = 1; for(col = 2; col <= A.n; col++) position[col] = position[col-1] + num[col-1]; for(p = 1; p <= A.len; p++) { col = A.data[p].col; q = position[col]; B->data[q].row = A.data[p].col; B->data[q].col = A.data[p].row; B->data[q].e = A.data[p].e; position[col]++; } } } //快速轉置法 int main(void) { TSMatrix A; TSMatrix B; int a[R][C], i = 1; while(i){ create(A, a, B); } return 0; }
運行結果: