1. 程式人生 > >資料結構:稀疏矩陣的壓縮儲存

資料結構:稀疏矩陣的壓縮儲存

問題提出:矩陣儲存壓縮 分析:儘可能地壓縮資料量;壓縮後仍然可以比較容易地進行各項基本操作. 兩類矩陣的壓縮儲存:特殊矩陣;稀疏矩陣. 稀疏矩陣的壓縮儲存思想: -儲存非零元:值;位置(行列號) -儲存適當的輔助資訊:行數;列數;非零元的個數 三元組<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;

在這裡插入圖片描述在這裡插入圖片描述