问题提出:矩阵存储压缩
分析:尽可能地压缩数据量;压缩后仍然可以比较容易地进行各项基本操作.
两类矩阵的压缩存储:特殊矩阵;稀疏矩阵.
稀疏矩阵的压缩存储思想:
-存储非零元:值;位置(行列号)
-存储适当的辅助信息:行数;列数;非零元的个数
三元组
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<
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<
②按照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
其中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;