列增序转置法
采用按照被转置矩阵三元组表A的列序递增额顺序进行转置,并依次送入三元组表B中
(A的列增序就是B的行增序)
具体做法:
找出第一行全部元素:第一遍从头至尾扫描三元组表A,找出其中所有col为1的三元组,
转置后按顺序送到三元组表中
(A是行增序的,所以扫描的时候,同样的列,行数越大,
满足三元组B在行增序的情况下,列也是增序)
接着扫描A找A.col=2,以此类推,直到扫描完
算法的时间消耗主要在双重循环中,时间复杂度 O(A.n*A.len)
最坏的情况为A.len=A.m*A.n 时间复杂度 O(A.m*A.n^2)
所以 列增序转置法方法 只适合 稀疏矩阵的转置
#define MAXN 200
typedef struct
{
int row,col;
int elem;
}Triple;
typedef struct
{
Triple data[MAXN];
int m,n,len;
}TripleMatrix;
void TransposeTSMatric(TripleMatrix *A,TripleMatrix *B)
{
int i,j,k;
B->m=A->n; B->n=A->m; B->len=A->len;
if(B->len>0)
{
j=0;
for(k=1;k<=A->n;k++) //如果列数可以为0的话,k就得从0开始了,k<A->n;
{
for(i=0;i<A->len;i++) //但data的下标无论何时都是从0开始的
{
if(A->data[i].col==k)
{
B->data[j].row=A->data[i].col;
B->data[j].col=A->data[i].row;
B->data[j].elem=A->data[i].elem;
j++;
}
}
}
}
}
void CreateTriple(TripleMatrix *p,int n) //因为有->,所以用指针传方便
{
int cnt;
for(cnt=0;cnt<n;cnt++) //i从0开始,是因为addtriple这个函数while跳出的小于号决定的
{
scanf("%d%d%d",&p->data[cnt].row,&p->data[cnt].col,&p->data[cnt].elem); //因为不是链表存储结构,所以不用malloc构建空间
}
p->len=cnt; //for里不要再习惯i了
}
void Print(TripleMatrix *c)
{
int cnt;
printf("\n");
for(cnt=0;cnt<(c->len);cnt++)
{
printf("%d %d %d\n",c->data[cnt].row,c->data[cnt].col,c->data[cnt].elem);
}
}
int main()
{
int n;
scanf("%d",&n);
TripleMatrix a,b;
CreateTriple(&a,n);
TransposeTSMatric(&a,&b);
Print(&b);
}
/*
测试用例:
8
1 2 13
1 3 9
3 1 -3
3 6 14
4 3 24
5 2 18
6 1 15
6 4 -7
测试结果:
1 3 -3
1 6 15
2 1 13
2 5 18
3 1 9
3 4 24
4 6 -7
6 3 14
*/