今天学了稀疏矩阵的转置算法,稀疏矩阵主要是为了节省存储空间,因为实际生活中对于一组数据只有比较少的数据是有意义的,所以可以用稀疏矩阵来存储那些有意义的数据,而把没有用的数据省略掉,而现在计算机中二维矩阵主要是行优先存放,所以稀疏矩阵的存储顺序就以行优先,每个元素包含三个数据:行号;‘列号;值;而稀疏矩阵本身也有三个数据:矩阵的行数,矩阵的列数,矩阵中非零元素的个数;那么矩阵的转置也以行优先的顺序存放,如何由原稀疏矩阵得到转置矩阵,并以行优先排列的稀疏矩阵来表示。下面提供了两种方法求解:
//稀疏矩阵的转置算法(行优先)
#define Max 100 //最多有100个非零元素
#define Maxn 110 //列最多为110
typedef int type;
typedef struct{
int row,col;
type value;
}node;
typedef struct{
node data[Max];
int m,n,num;
}SpGrap;
//原矩阵以行优先存放,求矩阵转置,转置后的矩阵也以行优先存放
//way 1 最简单的转置算法,复杂度为O(N*M)
void Z_z(SpGrap s,SpGrap *t){
t->n=s.m;
t->m=s.n;
t->num=s.num;
int i,j,index=0;
if(t->num>0){
for(i=1;i<=s.n;i++){
for(j=0;j<s.num;j++){
if(s.data[j].col==i){
t->data[index].row=s.data[j].col;
t->data[index].col=s.data[j].row;
t->data[index++].value=s.data[j].value;
}
}
}
}
}
//way 2快速转置算法?复杂度为O(N)
void Z_z(SpGrap s,SpGrap *t){
t->n=s.m;
t->m=s.n;
t->num=s.num;
if(t->num>0){
int i,numb[Maxn+1],pos[Maxn+1];
memset(numb,0,sizeof(numb));
for(i=0;i<t->num;i++)
numb[s.data[i].col]++;
pos[1]=0;
for(i=2;i<=s.n;i++)
pos[i]=pos[i-1]+num[i-1];
for(i=0;i<t->num;i++){
int temp=s.data[i].col;
t->data[pos[temp]].row=s.data[i].col;
t->data[pos[temp]].col=s.data[i].row;
t->data[pos[temp]].value=s.data[i].value;
pos[temp]++;
}
}
}
这两种的思想都基本一样,以原矩阵的列为优先,然后又由稀疏矩阵的特征来求解转置。当实现方式不一样,前者简单但复杂度更高,而后者思想上更难,但复杂度更低。