導航:首頁 > 文件處理 > 稀疏矩陣的壓縮存儲的作用

稀疏矩陣的壓縮存儲的作用

發布時間:2022-09-10 15:05:05

❶ 特殊矩陣和稀疏矩陣哪一種採用壓縮存儲會失去隨機存取的功能為什麼

稀疏矩陣壓縮存儲後,必會失去隨機存取功能.
稀疏矩陣在採用壓縮存儲後將會失去隨機存儲的功能.因為在這種矩陣中,非零元素的分布是沒有規律的,為了壓縮存儲,就將每一個非零元素的值和它所在的行、列號做為一個結點存放在一起,這樣的結點組成的線性表中叫三元組表,它已不是簡單的向量,所以無法用下標直接存取矩陣中的元素.

❷ 對稀疏矩陣進行壓縮的目的

我給你源碼記得頂我啊!!最主要的是把分給我哦!!
include<time.h>/*用於下面的srand((unsigned)time(NULL));函數的頭文件*/
#include<stdio.h>
#include<stdlib.h>
#define MAX_ARRAY_DIM 2
#define MAXSIZE 100
typedef struct
{
int aa[MAX_ARRAY_DIM];
int dim;
int *base;
}array;
typedef struct
{
int i,j;/*記錄非零元的行與列坐標*/
int e;/*記錄非零原的數值*/
}triple;/*構成非零元素*/
typedef struct
{
triple data[MAXSIZE];/*預期非零原最大個數*/
int *rpos;/*記錄各行第一個非零原的位置表*/
int mu,nu,tu;/*記錄稀疏矩陣的行列和非零原個數*/
}tsmatrix;
main()
{
void initarray(array *a);/*數組初始化*/
void createsMatrix(array *a);/*創建稀疏矩陣*/
void inittsmatrix(array *a,tsmatrix *m);/*初始化稀疏矩陣三元組*/
void outputtsmatrix(tsmatrix *m);/*輸出稀疏矩陣*/
void destroysmatrix(array *a);/*銷毀稀疏矩陣*/
void outputarray(array *a);/*輸出數組*/
void subtmatrix(tsmatrix *m,tsmatrix *n,tsmatrix *q);/*系數矩陣相減*/
void addsmatrix(tsmatrix *m,tsmatrix *n,tsmatrix *q);/*系數矩陣相加*/
void multsmatrix(tsmatrix *m,tsmatrix *n,tsmatrix *q);/*稀疏矩陣相乘*/
array a;
tsmatrix m,n,q;
int flag1=1,i;
srand((unsigned)time(NULL));
initarray(&a);/*初始化數組*/
createsMatrix(&a);/*創建稀疏矩陣*/
inittsmatrix(&a,&m);/*初始化稀疏矩陣三元組*/
outputtsmatrix(&m);/*輸出稀疏矩陣*/
outputarray(&a);/*輸出數組*/
destroysmatrix(&a);/*銷毀原數組*/
initarray(&a);/*初始化數組*/
createsMatrix(&a);/*創建稀疏矩陣*/
inittsmatrix(&a,&n);/*初始化稀疏矩陣三元組*/
outputtsmatrix(&n);/*輸出稀疏矩陣*/
outputarray(&a);/*輸出數組*/
destroysmatrix(&a);/*銷毀原數組*/
printf("2個三元數組已經創建成功,您要進行什麼操作?\n1.(m+n)\n2.(m-n)\n3.(m*n)\n4.(n-m)\n");
while(flag1)
{
fflush(stdin);
scanf("%d",&i);
switch(i)
{
case 1:addsmatrix(&m,&n,&q);flag1=0;break;
case 2:subtmatrix(&m,&n,&q);flag1=0;break;
case 3:multsmatrix(&m,&n,&q);flag1=0;break;
case 4:subtmatrix(&n,&m,&q);flag1=0;break;
default:printf("輸入錯誤請重新輸入\n您要進行什麼操作?1.(m+n)\n2.(m-n)\n3.(m*n)\n4.(n-m)\n\n");
}
}
printf("運算結果為\n");
outputtsmatrix(&q);/*輸出運算結果*/
}
void initarray(array *a)/*創建數組*/
{
int i,j;
printf("請輸入要創建的維數,(由於這里的作用是創建稀疏矩陣,建議輸入2)\n");
scanf("%d",&a->dim);
if(a->dim!=MAX_ARRAY_DIM)
{
printf("輸入維數超過界限\n");
exit(1);
}
for(i=0;i<a->dim;i++)
{
printf("請輸入第%d維的數據",i+1);
scanf("%d",&a->aa[i]);
if(a->aa[i]<1)
{
printf("輸入超過范圍\n");
exit(1);
}
}
j=1;
for(i=0;i<a->dim;i++)
j*=a->aa[i];
if(!(a->base=(int *)malloc(j*sizeof(int))))
{
printf("開辟空間失敗\n");
exit(1);
}
printf("數組創建成功\n");
}
void createsMatrix(array *a)/*創建稀疏矩陣*/
{
int i,j,k,l,m,n,flag1;
printf("是手動輸入還是電腦自行創建?\n選1.電腦自行創建\n選0.手動創建\n");
scanf("%d",&i);
if(i!=1&&i!=0)
{
printf("輸入格式錯誤\n");
exit(1);
}
if(i==0)/*手動輸入*/
{
printf("請輸入\n");
for(j=0;j<a->aa[0];j++)
{
for(k=0;k<a->aa[1];k++)
scanf("%d",&a->base[j*a->aa[1]+k]);
printf("\n");
}
}
else/*電腦自動輸入*/
{
l=rand()%(a->aa[0]*a->aa[1]/4)+1;/*預期計算要輸入多少個非零元*/
for(j=0;j<a->aa[0];j++)/*先將程序中所有的元素賦予0*/
for(k=0;k<a->aa[1];k++)
a->base[j*a->aa[1]+k]=0;
m=0;
while(m<l)/*輸入l個非零元*/
{
flag1=1;
while(flag1)/*被賦予的元素原本必須是零*/
{
i=rand()%a->aa[0];/*自動選擇行*/
j=rand()%a->aa[1];/*自動選擇列*/
if(a->base[i*a->aa[1]+j]==0)/*所選擇的元素是0*/
flag1=0;/*推出循環,否則繼續循環直到,是零為止*/
}
flag1=1;
a->base[i*a->aa[1]+j]=rand()%10;/*賦值10以內*/
n=rand()%10;
if(n<5)
a->base[i*a->aa[1]+j]*=-1;/*輸入正負*/
m++;
}
}
}
void inittsmatrix(array *a,tsmatrix *m)/*稀疏矩陣非零原初始化*/
{
int i,j,k=0,*num;
for(i=0;i<a->aa[0];i++)/*輸入非零原坐標及數據*/
for(j=0;j<a->aa[1];j++)
if(a->base[i*a->aa[1]+j]!=0)
{
m->data[k+1].i=i+1;
m->data[k+1].j=j+1;
m->data[k+1].e=a->base[i*a->aa[1]+j];
k++;
}
m->mu=a->aa[0];/*記錄行*/
m->nu=a->aa[1];/*記錄列*/
m->tu=k;/*記錄非零原數量*/
if(!(num=(int *)malloc((m->mu+1)*sizeof(int))))/*num用於記錄每行的非零原的個數*/
{
printf("空間開辟失敗\n");
exit(1);
}
if(!(m->rpos=(int *)malloc((m->mu+1)*sizeof(int))))/*本人認為數據結構上的rpos定義有錯誤,如果某一行全都是非零元那m->rpos[i]=0並不是m->rpos[i-1]+num[i-1]所以以下的rpos操作可能與書上的原意不符*/
{
printf("空間開辟失敗\n");
exit(1);
}
for(i=0;i<=m->mu;i++)/*初始化num*/
num[i]=0;
for(i=1;i<=m->tu;i++)/*記錄每行非零原的個數*/
++num[m->data[i].i];
if(num[1]==0)/*如果第一行沒有非零原的話那m->rops[1]=0,這就是我修改的原因,如果按照書上寫的話,那應該是1,對以後的操作有麻煩*/
{
m->rpos[1]=0;
j=0;
}
else/*否則記1*/
{
m->rpos[1]=1;
j=num[1];
}
for(i=2;i<=m->mu;i++)/*運算*/
{
if(num[i]==0)
m->rpos[i]=0;/*當前這一行並沒有非零元所以記錄1*/
else/*否則記錄所對應的序列號*/
{
m->rpos[i]=j+1;
j+=num[i];
}
if(j>=m->tu)/*如果j的數量已經等於所有非零原的數量,那就應該退出循環*/
break;
}
while(i<=m->mu)/*如果半路退出循環,那麼剩下的每行,都沒有非零原*/
i++,m->rpos[i]=0;
}
void outputtsmatrix(tsmatrix *m)/*輸出稀疏矩陣*/
{
int i;
printf("三元組表為\n");
for(i=1;i<=m->tu;i++)
printf("%d行 %d列 %d\n",m->data[i].i,m->data[i].j,m->data[i].e);
printf("行為%d列為%d\n",m->mu,m->nu);
for(i=1;i<=m->mu;i++)
printf("%d行的第一個元素所在位置表的位置是%d\n",i,m->rpos[i]);

}
void destroysmatrix(array *a)/*銷毀稀疏矩陣*/
{
if(!a->base)exit(1);
free(a->base);a->base=NULL;
printf("\n稀疏矩陣數組銷毀成功(*^__^*) \n\n");
}
void outputarray(array *a)/*輸出數組*/
{
int i,j;
for(i=0;i<a->aa[0];i++)
{
for(j=0;j<a->aa[1];j++)
printf("%2d ",a->base[i*a->aa[1]+j]);
printf("\n");
}
}
void smatrix(tsmatrix *m,tsmatrix *t)/*復制稀疏矩陣*/
{
int i;
t->mu=m->mu,t->nu=m->nu,t->tu=m->tu;
if(!(t->rpos=(int *)malloc((t->mu+1)*sizeof(int))))
{
printf("開辟控制項失敗\n");
exit(1);
}
if(t->tu)
{
for(i=1;i<=m->tu;i++)
{
t->data[i].i=m->data[i].i;
t->data[i].j=m->data[i].j;
t->data[i].e=m->data[i].e;
}
}
for(i=1;i<=t->mu;i++)
t->rpos[i]=m->rpos[i];
}
void subtmatrix(tsmatrix *m,tsmatrix *n,tsmatrix *q)/*稀疏矩陣相減*/
{
int i,j,k,a,b,c,x,y,z,*num;
q->mu=m->mu>n->mu?m->mu:n->mu;
q->nu=m->nu>n->nu?m->nu:n->nu;
q->tu=0;
if(!(num=(int *)malloc((q->mu+1)*sizeof(int))))
{
printf("創建空間失敗\n");
exit(1);
}
if(!(q->rpos=(int *)malloc((q->mu+1)*sizeof(int))))
{
printf("創建空間失敗\n");
exit(1);
}
for(i=1;i<=q->mu;i++)
num[i]=0;
if(m->tu==0)
smatrix(n,q);
else if(n->tu==0)
smatrix(m,q);
else
{
i=j=k=1;
while(i<=m->tu&&j<=n->tu)
{
a=m->data[i].i;
b=m->data[i].j;
c=m->data[i].e;/*分別記錄m的3元組的數據*/
x=n->data[j].i;
y=n->data[j].j;
z=n->data[j].e;
if(a==x)/*如果m,n行相等*/
{
if(b==y)/*如果行列都相等*/
{
if(c-z!=0)/*如果m-n!=0*/
{
num[a]++;
q->data[k].i=a;
q->data[k].j=b;
q->data[k].e=c-z;
k++;
}
i++,j++;/*無論是否m-n==0i,j都要+1*/
}
else if(b<y)/*如果行相等但是列不相等q下一個三元組應該取坐標相對較小的*/
{
num[a]++;
q->data[k].i=a;
q->data[k].j=b;
q->data[k].e=c;
k++;
i++;
}
else if(b>y)
{
num[x]++;
q->data[k].i=x;
q->data[k].j=y;
q->data[k].e=-z;
k++;j++;
}
else
printf("不可能出現的事情\n");
}
else if(a>x)
{
num[x]++;
q->data[k].i=x;
q->data[k].j=y;
q->data[k].e=-z;
k++;j++;
}
else if(a<x)
{
num[a]++;
q->data[k].i=a;
q->data[k].j=b;
q->data[k].e=c;
k++;i++;
}
else
printf("不可能發生的事情\n");
}
if(i>m->tu&&j<=n->tu)/*如果m的三元組記錄完了但是n的三元組沒有記錄完那麼剩下的應該全復制*/
{
while(j<=n->tu)
{
num[n->data[j].i]++;
q->data[k].i=n->data[j].i;
q->data[k].j=n->data[j].j;
q->data[k++].e=-n->data[j++].e;
}
}
else if(j>n->tu&&i<=m->tu)/*如果n的三元組記錄完了但是m的三元組沒有記錄完那麼剩下的應該全復制*/
{
while(i<=m->tu)
{
n->data[m->data[i].i].i;
q->data[k].i=m->data[i].i;
q->data[k].j=m->data[i].j;
q->data[k++].e=m->data[i++].e;
}
}
q->tu=k-1;
if(num[1]==0)/*如果第一行沒有非零原的話那m->rops[1]=0,這就是我修改的原因,如果按照書上寫的話,那應該是1,對以後的操作有麻煩*/
{
q->rpos[1]=0;
j=0;
}
else/*否則記1*/
{
q->rpos[1]=1;
j=num[1];
}
for(i=2;i<=q->mu;i++)/*運算*/
{
if(num[i]==0)
q->rpos[i]=0;/*當前這一行並沒有非零元所以記錄1*/
else/*否則記錄所對應的序列號*/
{
q->rpos[i]=j+1;
j+=num[i];
}
if(j>=q->tu)/*如果j的數量已經等於所有非零原的數量,那就應該退出循環*/
break;
}
while(i<=q->mu)/*如果半路退出循環,那麼剩下的每行,都沒有非零原*/
{
i++;
q->rpos[i]=0;
}
}
}
void addsmatrix(tsmatrix *m,tsmatrix *n,tsmatrix *q)/*稀疏矩陣相加*/
{
int i,j,k,a,b,c,x,y,z,*num;
q->mu=m->mu>n->mu?m->mu:n->mu;
q->nu=m->nu>n->nu?m->nu:n->nu;
q->tu=0;
if(!(num=(int *)malloc((q->mu+1)*sizeof(int))))
{
printf("創建空間失敗\n");
exit(1);
}
if(!(q->rpos=(int *)malloc((q->mu+1)*sizeof(int))))
{
printf("創建空間失敗\n");
exit(1);
}
for(i=1;i<=q->mu;i++)
num[i]=0;
if(m->tu==0)
smatrix(n,q);
else if(n->tu==0)
smatrix(m,q);
else
{
i=j=k=1;
while(i<=m->tu&&j<=n->tu)
{
a=m->data[i].i;
b=m->data[i].j;
c=m->data[i].e;/*分別記錄m的3元組的數據*/
x=n->data[j].i;
y=n->data[j].j;
z=n->data[j].e;
if(a==x)/*如果m,n行相等*/
{
if(b==y)/*如果行列都相等*/
{
if(c+z!=0)/*如果m+n!=0*/
{
num[a]++;
q->data[k].i=a;
q->data[k].j=b;
q->data[k].e=c+z;
k++;
}
i++,j++;/*無論是否m+n==0i,j都要+1*/
}
else if(b<y)/*如果行相等但是列不相等q下一個三元組應該取坐標相對較小的*/
{
num[a]++;
q->data[k].i=a;
q->data[k].j=b;
q->data[k].e=c;
k++;
i++;
}
else if(b>y)
{
num[x]++;
q->data[k].i=x;
q->data[k].j=y;
q->data[k].e=z;
k++;j++;
}
else
printf("不可能出現的事情\n");
}
else if(a>x)
{
num[x]++;
q->data[k].i=x;
q->data[k].j=y;
q->data[k].e=z;
k++;j++;
}
else if(a<x)
{
num[a]++;
q->data[k].i=a;
q->data[k].j=b;
q->data[k].e=c;
k++;i++;
}
else
printf("不可能發生的事情\n");
}
if(i>m->tu&&j<=n->tu)/*如果m的三元組記錄完了但是n的三元組沒有記錄完那麼剩下的應該全復制*/
{
while(j<=n->tu)
{
num[n->data[j].i]++;
q->data[k].i=n->data[j].i;
q->data[k].j=n->data[j].j;
q->data[k++].e=n->data[j++].e;
}
}
else if(j>n->tu&&i<=m->tu)/*如果n的三元組記錄完了但是m的三元組沒有記錄完那麼剩下的應該全復制*/
{
while(i<=m->tu)
{
n->data[m->data[i].i].i;
q->data[k].i=m->data[i].i;
q->data[k].j=m->data[i].j;
q->data[k++].e=m->data[i++].e;
}
}
q->tu=k-1;
if(num[1]==0)/*如果第一行沒有非零原的話那m->rops[1]=0,這就是我修改的原因,如果按照書上寫的話,那應該是1,對以後的操作有麻煩*/
{
q->rpos[1]=0;
j=0;
}
else/*否則記1*/
{
q->rpos[1]=1;
j=num[1];
}
for(i=2;i<=q->mu;i++)/*運算*/
{
if(num[i]==0)
q->rpos[i]=0;/*當前這一行並沒有非零元所以記錄1*/
else/*否則記錄所對應的序列號*/
{
q->rpos[i]=j+1;
j+=num[i];
}
if(j>=q->tu)/*如果j的數量已經等於所有非零原的數量,那就應該退出循環*/
break;
}
while(i<=q->mu)/*如果半路退出循環,那麼剩下的每行,都沒有非零原*/
{
i++;
q->rpos[i]=0;
}
}
}
void multsmatrix(tsmatrix *m,tsmatrix *n,tsmatrix *q)/*稀疏矩陣相乘*/
{
int i,j,k,l,o,p,x,y,*a,*num;
if(!(a=(int *)malloc(((m->mu+1)*(n->nu+1))*sizeof(int))))/*創建一個跟q相同大小的空間用來記錄此坐標是否已經輸入一個數*/
{
printf("開辟空間失敗\n");
exit(1);
}
if(m->nu!=n->mu)
{
printf("不匹配\n");
exit(1);
}
q->mu=m->mu,q->nu=n->nu,q->tu=0;/*初始化*/
if(!(num=(int *)malloc((m->mu+1)*sizeof(int))))
{
printf("開辟空間失敗\n");
exit(1);
}
if(!(q->rpos=(int *)malloc((q->mu+1)*sizeof(int))))
{
printf("空間開辟失敗");
exit(1);
}
for(i=1;i<=q->mu;i++)
num[i]=0;
if(m->tu*n->tu!=0)
{
for(i=1;i<=m->mu;i++)/*初始化a數組*/
for(j=1;j<=n->nu;j++)
a[i*n->nu+j]=0;
for(i=1;i<=m->tu;i++)
{
o=m->data[i].i;
p=m->data[i].j;
if(n->rpos[p]==0)
continue;
l=p+1;
while(n->rpos[l]==0&&l<=n->mu)
l++;
if(l>n->mu)
j=n->tu+1;
else
j=n->rpos[l];
for(k=n->rpos[p];k<j;k++)/*k-j的范圍是本行非零遠的個數*/
{
x=n->data[k].i;/*x,y分別是n->data[k]的行和列*/
y=n->data[k].j;
if(a[o*n->nu+y]!=0)
q->data[a[o*n->nu+y]].e+=m->data[i].e*n->data[k].e;/*如果此空間已經輸入一個數了,那麼在相應的位置累加*/
else
{
q->data[++q->tu].e=m->data[i].e*n->data[k].e;
q->data[q->tu].i=o;
q->data[q->tu].j=y;
a[o*n->nu+y]=q->tu;/*此位置記錄q->tu*/
num[o]++;
}
}
}
for(i=1;i<=q->mu;i++)
printf("%d ",num[i]);
if(num[1]==0)/*如果第一行沒有非零原的話那m->rops[1]=0,這就是我修改的原因,如果按照書上寫的話,那應該是1,對以後的操作有麻煩*/
{
q->rpos[1]=0;
j=0;
}
else/*否則記1*/
{
q->rpos[1]=1;
j=num[1];
}
for(i=2;i<=q->mu;i++)/*運算*/
{
if(num[i]==0)
q->rpos[i]=0;/*當前這一行並沒有非零元所以記錄1*/
else/*否則記錄所對應的序列號*/
{
q->rpos[i]=j+1;
j+=num[i];
}
if(j>=q->tu)/*如果j的數量已經等於所有非零原的數量,那就應該退出循環*/
break;
}
while(i<=q->mu)/*如果半路退出循環,那麼剩下的每行,都沒有非零原*/
i++,q->rpos[i]=0;
}
}

❸ 稀疏矩陣的壓縮存儲思想

為了節省存儲空間並且加快處理速度,需要對這類矩陣進行壓縮存儲,壓縮存儲的原則是:不重復存儲相同元素;不存儲零值元素。稀疏矩陣,有三元組表示法、帶輔助行向量的二元組表示法(也即行邏輯鏈表的順序表),十字鏈表表示法等。演算法基本思想:num[col]:第col列的非零元素個數;cpot[col]:第col列第一個非零元在b.data中的恰當位置;在轉置過程中,指示該列下一個非零元在b.data中的位置。

❹ 特殊矩陣和稀疏矩陣哪一種壓縮存儲後失去隨機存取的功能為什麼

稀疏矩陣壓縮存儲後,必會失去隨機存取功能。稀疏矩陣在採用壓縮存儲後將會失去隨機存儲的功能。因為在壓縮存儲當中,非零元素的分布是沒有規律的,為了壓縮存儲,就將每一個非零元素的值和它所在的行、列號做為一個結點存放在一起,即三元組表,它不是簡單的向量,所以無法用下標直接存取矩陣中的元素。

❺ 稀疏矩陣的壓縮存儲只需要存儲什麼

非零元素。

對於一個用二維數組存儲的稀疏矩陣Amn,如果假設存儲每個數組元素需要L個位元組,那麼存儲整個矩陣需要m*n*L個位元組。但是,這些存儲空間的大部分存放的是0元素,從而造成大量的空間浪費。為了節省存儲空間,可以只存儲其中的非0元素。

(5)稀疏矩陣的壓縮存儲的作用擴展閱讀

稀疏矩陣演算法的最大特點是通過只存儲和處理非零元素從而大幅度降低存儲空間需求以及計算復雜度,代價則是必須使用專門的稀疏矩陣壓縮存儲數據結構。稀疏矩陣演算法是典型的不規則演算法,計算訪存比很低,並且計算過程中的訪存軌跡與稀疏矩陣的稀疏結構相關。

❻ 矩陣的壓縮存儲是什麼

二維數組在形式上是矩陣,因此一般用二維數組來存儲矩陣。在不壓縮存儲的情況下,矩陣採用按行優先或按列優先方式存儲,佔用的存儲單元數等於矩陣的元素個數。在實際應用中,經常出現一些階數很高的矩陣,同時在矩陣中非零元素呈某種規律分布或者矩陣中有大量的零元素,若仍然用常規方法存儲,可能存儲重復的非零元素或零元素,這將造成存儲空間的大量浪費。因此對這類矩陣進行壓縮存儲,從而合理地利用存儲空間。

為了節省存儲空間,可以利用特殊矩陣的規律,對它們進行壓縮存儲,也就是說為多個值相同的元素只分配一個存儲單元,對零元素不分配空間。適合壓縮存儲的矩陣一般是值相同的元素或者零元素在矩陣中分布有一定規律的特殊矩陣和稀疏矩陣。常見的特殊矩陣有對稱矩陣、三角矩陣和對角矩陣。

❼ 如何在工作空間查看稀疏矩陣

稀疏矩陣

設矩陣Amn中有s個非零元素,若s遠遠小於矩陣元素的總數(即s<<m×n),則稱A為稀疏矩陣。

1、稀疏矩陣的壓縮存儲
為了節省存儲單元,可只存儲非零元素。由於非零元素的分布一般是沒有規律的,因此在存儲非零元素的同時,還必須存儲非零元素所在的行號、列號,才能迅速確定一個非零元素是矩陣中的哪一個元素。稀疏矩陣的壓縮存儲會失去隨機存取功能。
其中每一個非零元素所在的行號、列號和值組成一個三元組(i,j,aij),並由此三元組惟一確定。
稀疏矩陣進行壓縮存儲通常有兩類方法:順序存儲和鏈式存儲。鏈式存儲方法【參見參考書目】。

2、三元組表
將表示稀疏矩陣的非零元素的三元組按行優先(或列優先)的順序排列(跳過零元素),並依次存放在向量中,這種稀疏矩陣的順序存儲結構稱為三元組表。
注意:
以下的討論中,均假定三元組是按行優先順序排列的。
【例】下圖(a)所示的稀疏矩陣A的三元組表表示見圖(b)

(1)三元組表的類型說明
為了運算方便,將矩陣的總行數、總列數及非零元素的總數均作為三元組表的屬性進行描述。其類型描述為:
#define MaxSize 10000 //由用戶定義
typedef int DataType; //由用戶定義
typedef struct { //三元組
int i,j;//非零元的行、列號
DataType v; //非零元的值
}TriTupleNode;

typedef struct{ //三元組表
TriTupleNode data[MaxSize]; //三元組表空間
int m,n,t; //矩陣的行數、列數及非零元個數
}TriTupleTable;

(2) 壓縮存儲結構上矩陣的轉置運算
一個m×n的矩陣A,它的轉置矩陣B是一個n×m的矩陣,且:
A[i][j]=B[j][i],0≤i<m,0≤j<n,
即A的行是B的列,A的列是B的行。
【例】下圖中的B和上圖中的A互為轉置矩陣。


①三元組表表示的矩陣轉置的思想方法
第一步:根據A矩陣的行數、列數和非零元總數確定B矩陣的列數、行數和非零元總數。
第二步:當三元組表非空(A矩陣的非零元不為0)時,根據A矩陣三元組表的結點空間data(以下簡稱為三元組表),將A的三元組表a->data置換為B的三元組表b->data。

②三元組表的轉置
方法一:簡單地交換a->data中i和j中的內容,得到按列優先順序存儲倒b->data;再將b->data重排成按行優先順序的三元組表。
方法二:由於A的列是B的行,因此,按a->data的列序轉置,所得到的轉置矩陣B的三元組表b->data必定是按行優先存放的。
按這種方法設計的演算法,其基本思想是:對A中的每一列col(0≤col≤a->n-1),通過從頭至尾掃描三元組表a->data,找出所有列號等於col的那些三元組,將它們的行號和列號互換後依次放人b->data中,即可得到B的按行優先的壓縮存貯表示。具體實現參見【動畫演示】

③具體演算法:
void TransMatrix(TriTupleTable *b,TriTupleTable *a)
{//*a,*b是矩陣A、B的三元組表表示,求A轉置為B
int p,q,col;
b->m=a->n; b->n=a->m; //A和B的行列總數互換
b->t=a->t; //非零元總數
if(b->t<=0)
Error("A=0"); //A中無非零元,退出
q=0;
for(col=0;col<a->n;col++) //對A的每一列
for(p=0;p<a->t;p++) //掃描A的三元組表
if(a->data[p].j==col){ //找列號為col的三元組
b->data[q).i=a->data[p].j;
b->data[q].j=a->data[p].i;
b->data[q].v=a->data[p].v;
q++;
}
} //TransMatrix

④演算法分析
該演算法的時間主要耗費在col和p的二重循環上:
若A的列數為n,非零元素個數t,則執行時間為O(n×t),即與A的列數和非零元素個數的乘積成正比。
通常用二維數組表示矩陣時,其轉置演算法的執行時間是O(m×n),它正比於行數和列數的乘積。
由於非零元素個數一般遠遠大於行數,因此上述稀疏矩陣轉置演算法的時間大於通常的轉置演算法的時間。

上一頁

3、帶行表的三元組表
為了方便某些矩陣運算,在按行優先存儲的三元組表中,加入一個行表來記錄稀疏矩陣中每行的非零元素在三元組表中的起始位置。這就是帶行表的三元組表。
(1)類型描述
#define MaxRow l00 //在三元組表定義前加入此最大行定義
typedef struct {
TriTupleNode data[MaxSize];
int RowTab[MaxRow];//行表,應保證m≤MaxRow
int m,n,t;
}RTriTupleTable;

(2)帶行表的三元組表的操作
① 對於任給行號i(0≤i≤m-1),能迅速地確定該行的第一個非零元在三元組表中的存儲位置為RowTab[i]
② RowTab[i](0≤i≤m-1)表示第i行之前的所有行的非零元數。
③ 第i行上的非零元數目為RowTab[i+1]-RowTab[i](0≤i≤m-2)
④ 最後一行(即第m-l行)的非零元數目為t-RowTab[m-1](t為矩陣的非零元總數)
注意:
若在行表中令RowTab[m]=t(要求MaxRow>m)會更方便 些,且t可省略。
帶行表的三元組表可改進矩陣的轉置演算法,具體【參閱其它參考書】。

4.稀疏矩陣壓縮存儲方式分析
(1) 三元組表和帶行表的三元組表的特點
相應的演算法描述較為簡單,但這類順序存儲方式對於非零元的位置或個數經常發生變化的矩陣運算就顯得不太適合。
【例】執行將矩陣B相加到矩陣A上的運算時,某位置上的結果可能會由非零元變為零元,但也可能由零元變為非零元,這就會引起在A的三元組表中進行刪除和插人操作,從而導致大量結點的移動。對此類運算採用鏈式存儲結構為宜。

(2)稀疏矩陣的鏈式結構
稀疏矩陣的鏈式結構有十字鏈表等方法,適用於非零元變化大的場合,比較復雜,可【參閱其它參考書】。

閱讀全文

與稀疏矩陣的壓縮存儲的作用相關的資料

熱點內容
操作系統代碼編譯 瀏覽:483
程序員東北大學 瀏覽:426
編譯忽略空字元 瀏覽:117
多店鋪阿里雲伺服器教程 瀏覽:378
單片機求初值 瀏覽:420
安卓機如何在電腦備份圖片 瀏覽:925
ca證書加密機價格 瀏覽:798
天乾地支年份演算法 瀏覽:796
程序員打造的視頻 瀏覽:7
java和php通信 瀏覽:680
為什麼黑程序員 瀏覽:163
程序員男生 瀏覽:456
戴爾文件夾內文件怎麼置頂 瀏覽:582
雲伺服器6m網速 瀏覽:722
vivo手機中國聯通伺服器地址 瀏覽:862
工程總控編譯失敗 瀏覽:707
燕趙紅楓app如何下載 瀏覽:867
php查殺軟體 瀏覽:878
教育管理學pdf 瀏覽:547
伺服器均衡怎麼使用 瀏覽:626