(13)稀疏矩陣的壓縮-三元組表(轉置)
阿新 • • 發佈:2019-02-06
若矩陣中的非零元素遠遠小於矩陣元素的個數,且分佈沒有規律,則稱這個矩陣為稀疏矩陣。
壓縮儲存是指對多個值相同的元素只分配一個儲存空間,對零元素不分配空間。
稀疏矩陣的壓縮儲存有兩種方法:三元組的順序儲存(三元組表)和鏈式儲存(十字連結串列)。
現在主要講三元組表,由於兩個階數不同的矩陣可能具有相同的非零元素,為了區別,在儲存三元組時,同時還應儲存該矩陣的行數、列數。通常為了運算的方便,也存放非零元素的個數。這種以順序儲存
壓縮儲存是指對多個值相同的元素只分配一個儲存空間,對零元素不分配空間。
稀疏矩陣的壓縮儲存有兩種方法:三元組的順序儲存(三元組表)和鏈式儲存(十字連結串列)。
現在主要講三元組表,由於兩個階數不同的矩陣可能具有相同的非零元素,為了區別,在儲存三元組時,同時還應儲存該矩陣的行數、列數。通常為了運算的方便,也存放非零元素的個數。這種以順序儲存
結構來表示三元組的線性表,稱之為三元組表。稀疏矩陣的儲存的三元組表的儲存結構可定義如下:
#define MAXSIZE 1000 //使用者自定義三元組最大個數 typedef int ElemType; typedef struct { //三元組 int row,col; //非零元素的行數和列數 ElemType e; //非零元素的值 }Triple; typedef struct { Triple data[MAXSIZE]; //三元組表 int m,n, len; //矩陣的行數、列數和非零個數 }TSMatrix;
(1)三元組表的矩陣轉置運算-“直接取,順序存”
但是每處理一列就要查遍三元組表,工作量比較大//轉置 TSMatrix TransTSMatrixSlow(TSMatrix a,TSMatrix b) { int q; b.m = a.n; b.n = a.m; b.len = a.len; if (b.len) { q = 0; //B中的非零個數 for (int j = 0; j < a.n;j++) { //按列轉置 for (int h = 0; h < a.len; h++) { if (j==a.data[h].col) { //本列中一個非零元素 b.data[q].row = a.data[h].col; b.data[q].col = a.data[h].row; b.data[q].e = a.data[h].e; q++; } } } } else { cout << "矩陣為空,無需轉置!" << endl; } return b; }
(2)三元組表的矩陣快速轉置運算-“順序取,直接存”
核心:若用number陣列記錄矩陣A中每列的非零元素個數,用position陣列記錄A中每列第一個非零元素在三元組表中的位置,則若第j-1列的第一個非零元素在position[j-1]的位置上,第j列的第一個非零元素必在第position[j-1]+number[j-1]位置上。//快速轉置 TSMatrix TransTSMatrixFast(TSMatrix a, TSMatrix b) { int number[MAXSIZE],position[MAXSIZE]; b.m = a.n; b.n = a.m; b.len = a.len; for (int j = 0; j < a.n;j++) { number[j] = 0; //將矩陣a每一列非零元素的個數初始化為零 } for (int t = 0; t < a.len; t++) { number[a.data[t].col]++; //求每一列非零元素的個數 } position[0] = 0; for (int j = 1; j < a.n; j++) { //a.data[]的第j列第一個非零元素在b.data中的序號 position[j] = position[j - 1] + number[j - 1]; } int j,q; for (int p = 0; p < a.len; p++) { //求轉置矩陣b的三元組表 j = a.data[p].col; q = position[j]; 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[j]++; } return b; }
完整程式碼:
#include<iostream>
using namespace std;
#define MAXSIZE 1000 //使用者自定義三元組最大個數
typedef int ElemType;
typedef struct { //三元組
int row,col; //非零元素的行數和列數
ElemType e; //非零元素的值
}Triple;
typedef struct {
Triple data[MAXSIZE]; //三元組表
int m,n, len; //矩陣的行數、列數和非零個數
}TSMatrix;
//輸出矩陣
void print(TSMatrix a){
int k;
for (int i = 0; i < a.m;i++) {
for (int j = 0; j < a.n;j++) {
k = 0;
for(int h=0;h<a.len;h++){
if (i == a.data[h].row && j==a.data[h].col) {
cout <<" "<< a.data[h].e;
k = 1;
}
}
if (k == 0) {
cout << " " << k;
}
}
cout << endl;
}
}
//轉置
TSMatrix TransTSMatrixSlow(TSMatrix a,TSMatrix b) {
int q;
b.m = a.n;
b.n = a.m;
b.len = a.len;
if (b.len) {
q = 0; //B中的非零個數
for (int j = 0; j < a.n;j++) { //按列轉置
for (int h = 0; h < a.len; h++) {
if (j==a.data[h].col) { //本列中一個非零元素
b.data[q].row = a.data[h].col;
b.data[q].col = a.data[h].row;
b.data[q].e = a.data[h].e;
q++;
}
}
}
}
else {
cout << "矩陣為空,無需轉置!" << endl;
}
return b;
}
//快速轉置
TSMatrix TransTSMatrixFast(TSMatrix a, TSMatrix b) {
int number[MAXSIZE],position[MAXSIZE];
b.m = a.n;
b.n = a.m;
b.len = a.len;
for (int j = 0; j < a.n;j++) {
number[j] = 0; //將矩陣a每一列非零元素的個數初始化為零
}
for (int t = 0; t < a.len; t++) {
number[a.data[t].col]++; //求每一列非零元素的個數
}
position[0] = 0;
for (int j = 1; j < a.n; j++) { //a.data[]的第j列第一個非零元素在b.data中的序號
position[j] = position[j - 1] + number[j - 1];
}
int j,q;
for (int p = 0; p < a.len; p++) { //求轉置矩陣b的三元組表
j = a.data[p].col;
q = position[j];
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[j]++;
}
return b;
}
void main() {
TSMatrix A, B;
A.m = 5;
A.n = 6;
A.len = 7;
A.data[0].row = 0; A.data[0].col = 1; A.data[0].e = 6;
A.data[1].row = 0; A.data[1].col = 5; A.data[1].e = -2;
A.data[2].row = 2; A.data[2].col = 3; A.data[2].e = -8;
A.data[3].row = 3; A.data[3].col = 1; A.data[3].e = 3;
A.data[4].row = 3; A.data[4].col = 5; A.data[4].e = 7;
A.data[5].row = 4; A.data[5].col = 0; A.data[5].e = -12;
A.data[6].row = 4; A.data[6].col = 2; A.data[6].e = 9;
cout << "矩陣A為:" << endl;
print(A);
cout << "求係數矩陣A的轉置矩陣B?" << endl;
B = TransTSMatrixSlow(A,B);
cout << "轉置矩陣B為:" << endl;
print(B);
cout << endl;
B = TransTSMatrixFast(A,B);
print(B);
system("pause");
}