1. 程式人生 > >陣列及矩陣的壓縮儲存

陣列及矩陣的壓縮儲存

資料結構中的線性結構包括線性表,棧,佇列還有串,這些結構的資料元素都是不再分解的原子型別。陣列和廣義表可以看成是線性表在下述含義以上的擴充套件:表中的資料元素本身也是一個數據結構。

一、陣列

1、和線性表一樣,陣列中所有的資料元素都必須屬於統一資料型別。陣列中的每個資料元素都對應於一組下標(j1,j2,...,jn),每個下標有各自的取值範圍,0≤ji≤bi-1,bi稱為第i維的長度(i=1,2,3,...,n)。當n=1時,n維陣列就退化為定長的線性表。

n維陣列也可以看成是線性表的推廣。一個n維陣列型別可以定義為起資料元素為n-1維陣列型別的一維陣列型別。除了初始化和銷燬才做之外,陣列只有存取元素和修改元素值的操作。

2、一般採用順序儲存結構表示陣列。由於陣列是多維的,則用一組連續儲存單元儲存陣列的資料元素就得約定儲存次序。對二維陣列可有兩種儲存方式,即以列序為主序(高下標即最裡層下標優先)和以行序為主序(低下標即最外層下標優先)的儲存方式。

假設每個資料元素佔L個儲存單元,則二維陣列A中任一元素的儲存位置可由公式算出:LOC(i,j)=LOC(0,0)+(b2×i+j)L,LOC(0,0)是第一個元素a00的儲存位置。

二、矩陣的壓縮儲存

有效儲存矩陣的元,可使矩陣的各種運算能有效地進行。

所謂壓縮儲存:為多個值相同的元只分配一個儲存空間;對零元不分配空間。

稀疏矩陣的壓縮儲存:

這類矩陣,其非零元較零元少,且分佈沒有一定規律。假設在m*n的矩陣中,有t個元素不為零。令=t/(m*n),稱  為矩陣的稀疏因子。   《=0.05時稱為稀疏矩陣。

儲存局正式,除了儲存非零元的值以外,還必須記下他所在的行和列的位置(i,j),一個三元組(i,j,aij)唯一確定了矩陣A的一個非零元。

基於三元組表不同的表示方法可以引出稀疏矩陣不同的壓縮儲存方法。

1、三元組順序表

#define MAXSIZE 500
typedef struct{
int i,j;    //該非零元的行下標和列下標
ElemType e;}Triple;

typedef struct{
Triple data[MAXSIZE+1];  //非零元三元組表,data[0]未用 
int mu,nu,tu;    //矩陣的行數,列數和非零元個數
}TSMatrix;
data域中表示非零元的三元組是以行序為主序順序排列的。

快速轉置演算法:a.data和b.data表分別是稀疏矩陣M,T的非零元三元組表,T是M的轉置矩陣。如果預先確定矩陣M中每一列即T中每一行的地一個非零元在b.data中應有的位置,那麼在對a.data中的三元組依次作轉置時,就可直接放到b,data中恰當的位置上去,從而實現轉置時時間複雜度是線性的。

在轉置前,應先求得原矩陣M中每一列非零元的個數,進而求得每一列的第一個非零元在b.data中應有的位置。

Status FastTransposeSMatrix(TSMatrix M,TSMatrix *T)
 { //快速求稀疏矩陣M的轉置矩陣T
   T.mu=M.nu;
   T.nu=M.mu;
   T.tu=M.tu;
   if(T.tu)
   {
     for(col=1;col<=M.nu;++col)
       num[col]=0; //設初值 
     for(t=1;t<=M.tu;++t) //求M中每一列含非零元素個數 
       ++num[M.data[t].j];
     cpot[1]=1;
     for(col=2;col<=M.nu;++col) //求第col列中第一個非零元在b.data中的序號 
       cpot[col]=cpot[col-1]+num[col-1];
     for(p=1;p<=M.tu;++p)
     {
       col=M.data[p].j;
       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];  //下一次已+1
     }
   }
   return OK;
 }

2、行邏輯連結的順序表

此儲存結構可隨機存取任意一行的非零元。將快速轉置矩陣演算法中指示“行”資訊的輔助陣列cpot固定在稀疏矩陣的儲存結構中。

Typedef struct{
Triple data[MAXSIZE++1];
Int rpos[MAXRC+1];
Int mu,nu,tu;
}RLSMatrix;

矩陣乘積:Q=M*N

演算法描述:

Q初始化;
If(Q是非零矩陣){//逐行求積
For(arrow=1;arrow<=M.mu;++arow)
{//處理M中每一行
 ctemp[]=0;//累加器清零
計算Q中第arow行的積並存入ctemp[]中
將ctemp[]中非零元壓縮儲存到Q.data中
}
}
 

要點:學會快速轉置演算法中設定的輔助向量用法,即描述每一列中非零元個數的向量num[col]和指示每一列的第一個非零元在轉置矩陣三元組表中恰當位置的向量cpot[col].