稀疏矩阵的提出是基于存储的高效率考虑的,由于实际生活中不是每一个数据都是需要保存或记录的,或者说有很多数据都是重复的,比如都是0或者1等,那么就可以将不需要的数据抽象成数字0,或者是把相同的数据抽象成0,这样就只需要记录原数据量-不需要的数据量了,在这里,我们原本用一个矩阵记录数据,(称0元素比非零元素多的矩阵为稀疏矩阵),现在则可以用一个三元结点数组来等价表达了,方法是用行优先或者是列优先的顺序来顺次记录原矩阵中非零的元素,而三元结点中包含数据的行号,列号,和值。这样就可以在三元结点数组与矩阵之间建立一种一一对应的关系了,由于不需要记录不必要的数据,所以大大节省了存储空间。
那么现在我们讨论的问题是:当一个矩阵发生转置时,对应转置后的矩阵的三元结点数组是什么?或者说,如何由原三元数组来求转置后的三元结点数组,注意这里的三元结点数组都是以行优先(或列优先)存放数据的,如果不是这样的矩阵,那么就不能用该算法,下面是代码:
//稀疏矩阵的转置算法
#include <stdio.h>
#include <stdlib.h>
#define Max 100
typedef struct{
int row;
int col;
int value;
}trim;
typedef struct nutrim{
trim node[Max]; //最多为Max-1个非零元素
int m,n,num;
}nutrim,*pnutrim;
void transfor(pnutrim t){
printf("请输入稀疏矩阵的行数与列数以及非零元素:\n");
scanf("%d,%d,%d",&t->m,&t->n,&t->num);
if(t->num==0)
return ;
int i,j,k=1;
printf("请输入非零元素的行号列号以及值,行优先\n");
for(i=1;i<=t->num;i++)
scanf("%d,%d,%d",&t->node[i].row,&t->node[i].col,&t->node[i].value);
pnutrim s=(pnutrim)malloc(sizeof(nutrim));
for(i=1;i<=t->n;i++)
for(j=1;j<=t->num;j++)
if(t->node[j].col==i){
s->node[k].row=t->node[j].col;
s->node[k].col=t->node[j].row;
s->node[k++].value=t->node[j].value;
}
s->m=t->n;
s->n=t->m;
s->num=t->num;
printf("转置后的稀疏矩阵三元组表示,行优先:\n");
for(i=1;i<=s->num;i++)
printf("%d,%d,%d\n",s->node[i].row,s->node[i].col,s->node[i].value);
free(s);
}
int main(){
nutrim p;
pnutrim q=&p;
transfor(q);
return 0;
}
下面是测试数据:
请输入稀疏矩阵的行数与列数以及非零元素:
6,7,8
请输入非零元素的行号列号以及值,行优先
1,2,12
1,3,9
3,1,-3
4,3,24
5,2,18
6,1,15
6,4,-7
6,5,7
转置后的稀疏矩阵三元组表示,行优先:
1,3,-3
1,6,15
2,1,12
2,5,18
3,1,9
3,4,24
4,6,-7
5,6,7
Terminated with return code 0
Press any key to continue ...