資料結構:稀疏矩陣的壓縮儲存
問題提出:矩陣儲存壓縮 分析:儘可能地壓縮資料量;壓縮後仍然可以比較容易地進行各項基本操作. 兩類矩陣的壓縮儲存:特殊矩陣;稀疏矩陣. 稀疏矩陣的壓縮儲存思想: -儲存非零元:值;位置(行列號) -儲存適當的輔助資訊:行數;列數;非零元的個數 三元組<i,j,e>
0 | 12 | 9 | 0 | 0 | 0 | 0 |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 |
-3 | 0 | 0 | 0 | 0 | 14 | 0 |
0 | 0 | 24 | 0 | 0 | 0 | 0 |
0 | 18 | 0 | 0 | 0 | 0 | 0 |
15 | 0 | 0 | -7 | 0 | 0 | 0 |
一、三元組順序表 例1:稀疏矩陣得壓縮儲存(按行列號由小到大的有序表) 行號:1到6 列號:1到7
i | j | e |
---|---|---|
1 | 2 | 12 |
1 | 3 | 9 |
3 | 1 | -3 |
3 | 6 | 14 |
4 | 3 | 24 |
5 | 2 | 18 |
6 | 1 | 15 |
6 | 4 | -7 |
mu=6,nu=7,tu=8 //稀疏矩陣的三元順序表儲存(靜態分配)表示
#define MAXSIZE 100//<非零元素個數的最大值>
typedef struct{
int i,j;
ElemType e;
}Triple;
typedef struct{
Triple data{MAXSIZE+1};
int mu,nu,tu;
}TSMatrix;
1.建立:Status CreatSMatrix(TSMatrix &M) 2.輸出:void OutputSMatrix(TSMatrix &M)
0 | 12 | 9 | 0 | 0 | 0 | 0 |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 |
-3 | 0 | 0 | 0 | 0 | 14 | 0 |
0 | 0 | 24 | 0 | 0 | 0 | 0 |
0 | 18 | 0 | 0 | 0 | 0 | 0 |
15 | 0 | 0 | -7 | 0 | 0 | 0 |
i | j | e |
---|---|---|
1 | 2 | 12 |
1 | 3 | 9 |
3 | 1 | -3 |
3 | 6 | 14 |
4 | 3 | 24 |
5 | 2 | 18 |
6 | 1 | 15 |
6 | 4 | -7 |
M.mu=6,M.nu=7,M.tu=8
void OutputSMatrix(TSMatrix M){ int k=1; for(int i=1;i<=M.mu;i++){ cout<<endl; for(int j=1;j<M.nu;j++){ if((k<=M.tu)&&(M.data[k].i==i)&&M.data[k].j==j) cout<<M.data[k++].e; else cout<<0; } } }
3.稀疏矩陣的轉置運算 M
0 | 12 | 9 | 0 | 0 | 0 | 0 |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 |
-3 | 0 | 0 | 0 | 0 | 14 | 0 |
0 | 0 | 24 | 0 | 0 | 0 | 0 |
0 | 18 | 0 | 0 | 0 | 0 | 0 |
15 | 0 | 0 | -7 | 0 | 0 | 0 |
T
0 | 0 | -3 | 0 | 0 | 15 |
---|---|---|---|---|---|
12 | 0 | 0 | 0 | 18 | 0 |
9 | 0 | 0 | 24 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 |
0 | 18 | 0 | 0 | 0 | -7 |
0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 14 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 |
將M轉置為T的三元組順序表? M.data[1]
i | j | e |
---|---|---|
1 | 2 | 12 |
1 | 3 | 9 |
3 | 1 | -3 |
3 | 6 | 14 |
4 | 3 | 24 |
5 | 2 | 18 |
6 | 1 | 15 |
6 | 4 | -7 |
M.mu=6,M.nu=7,M.tu=8
T.data[1]
i | j | e |
---|---|---|
1 | 3 | -3 |
1 | 6 | 15 |
2 | 1 | 12 |
2 | 5 | 18 |
3 | 1 | 9 |
3 | 4 | 24 |
4 | 6 | -7 |
6 | 3 | 14 |
T.mu=7,T.nu=,T.tu=8 ①傳統轉置:
Status TransposeSMatrix(TSMatrix M,TSMatrix &T){
T.mu=M.nu;
T.nu=M.mu;
T.tu=M.tu;
if(T.tu){
q=1;
for(col=1;col<=M.nu;col++)
for(p=1;p<=M.tu;p++)
if(M.data[p].j==col){
T.data[q].i=M.data[p].j;
T.data[q].j=M.data[p].i;
T.data[q].e=M.data[p].e;
++q;
}
}
return OK;
}//TransposeSMatrix
一列一列查詢 時間複雜度:O(nutu) 適用於tu<<munu的情況 ②按照M的行序進行轉置(快速轉置) M
0 | 12 | 9 | 0 | 0 | 0 | 0 |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 |
-3 | 0 | 0 | 0 | 0 | 14 | 0 |
0 | 0 | 24 | 0 | 0 | 0 | 0 |
0 | 18 | 0 | 0 | 0 | 0 | 0 |
15 | 0 | 0 | -7 | 0 | 0 | 0 |
M.data[1]
i | j | e |
---|---|---|
1 | 2 | 12 |
1 | 3 | 9 |
3 | 1 | -3 |
3 | 6 | 14 |
4 | 3 | 24 |
5 | 2 | 18 |
6 | 1 | 15 |
6 | 4 | -7 |
M.mu=6,M.nu=7,M.tu=8
cpot[1]=1 cpot[col]=cpot[cpot-1]+num[col-1] 2<=col<=M.nu
col | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
num[col] | 2 | 2 | 2 | 1 | 0 | 1 | 0 |
cpot[col] | 1 | 3 | 5 | 7 | 8 | 8 | 9 |
Status FastTransposeSMatrix(TSMtarix M,TSMatrix &T){
T.mu=M.nu;
T.nu=M.mu;
T.tu=M.tu;
if(T.nu){
for(col=1;col<M.nu;col++) num[col]=0;
for(t=1;t<M.tu;t++) ++num[M.data[t].j];
cpot[1]=1;
for(col=2;col<=M.nu;col++)
cpot[col]=cpot[col-1]+num[col-1];
}
}
其中cpot[col]表示原矩陣中非零元在轉置之後的位置
Status FastTransposeSMatrix(TSMtarix M,TSMatrix &T){
T.mu=M.nu;
T.nu=M.mu;
T.tu=M.tu;
if(T.nu){
for(p=1;p<=M.tu;p++){
col=M.data[p];
q=cpot[col];
T.data[q].i=M.data[p].j;
T.data[q].j=M.data[p].i;
T.data[q].e=M.data[p].e;
++cpot[col];
}//for
}//if
}//FastTransposeSMatrix
二、行邏輯連結的順序表 引入
0 | 12 | 9 | 0 | 0 | 0 | 0 |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 |
-3 | 0 | 0 | 0 | 0 | 14 | 0 |
0 | 0 | 24 | 0 | 0 | 0 | 0 |
0 | 18 | 0 | 0 | 0 | 0 | 0 |
15 | 0 | 0 | -7 | 0 | 0 | 0 |
i | j | e |
---|---|---|
1 | 2 | 12 |
1 | 3 | 9 |
3 | 1 | -3 |
3 | 6 | 14 |
4 | 3 | 24 |
5 | 2 | 18 |
6 | 1 | 15 |
6 | 4 | -7 |
M.mu=6,M.nu=7,M.tu=8 M.rpos[1]=1 M.rpos[row]=M.rpos[row-1]+num[row-1] 2<=row<=M.mu
row | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|
num[row] | 2 | 0 | 2 | 1 | 1 | 2 |
M.rpos[row] | 1 | 3 | 3 | 5 | 6 | 7 |
思考:第row行元素在M.data表中的訪問起止位置? 起始位置:M.rpos[row] 終止位置:M.rpos[row+1]-1 (1<=row<=M.mu-1) M.tu (row=M.mu) 應用:實現稀疏矩陣的乘積運算! 十字連結串列:
typedef struct OLNode{
int i,j;
ElemType e;
struct OLNode *right,*down;
}OLNode,*OLink;
typedef struct{
OLink *rhead,*chead;
int mu,nu,tu;
}CrossList;