数据结构——稀疏矩阵的转置算法
本篇文章的代码基于【数据结构】【严蔚敏】【清华大学】
不是很想分函数来一遍解释
信息基本上都在注解里
直接上完整代码好了
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100 // 非零元个数的最大值
typedef int ElemType;
typedef int Status;
#define OK 1
#define N 4
struct Triple {
int i,j; // 行下标,列下标
ElemType e; // 非零元素值
};
struct TSMatrix {
Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用
int mu,nu,tu; // 矩阵的行数、列数和非零元个数
};
// 带行连接信息的三元组表
typedef struct{
Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用
int rpos[MAXSIZE+1]; // 各行的第一个非零元的位置表
int mu,nu,tu; // 矩阵的行数、列数和非零元个数
}RLSMatrix;
Status TransposeSMatrix(TSMatrix M,TSMatrix &T)
{
// 求稀疏矩阵M的转置矩阵T。算法5.1
// 时间复杂度为O(nu*tu)
// 当tu和mu*nu同一个数量级时,时间复杂度会变为O(mu*nu^2)
// 因此适用于tu<<mu*nu情况时
int p,q,col;
T.mu=M.nu;
T.nu=M.mu;
T.tu=M.tu;
if(T.tu) {
q=1;
for(col=1; col<=M.nu; ++col)
for(p=1; p<=M.tu; ++p)
if(M.data[p].j==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;
++q;
}
}
return OK;
}
Status TransposeSMatrix(RLSMatrix M,RLSMatrix &T)
{
// 求稀疏矩阵M的转置矩阵T. 算法5.2 快速转置
int p,q,t,col,*num;
num=(int *)malloc((M.nu+1)*sizeof(int));
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];
T.rpos[1]=1;
for(col=2; col<=M.nu; ++col) // 求M中第col中第一个非零元在T.data中的序号
T.rpos[col]=T.rpos[col-1]+num[col-1];
for(col=1; col<=M.nu; ++col) // T.rpos[col]的值不方便改变(别的操作会用到),故把值给到临时变量num[col]
num[col]=T.rpos[col];
for(p=1; p<=M.tu; ++p) {
col=M.data[p].j;
q=num[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;
++num[col];
}
}
free(num);
return OK;
}
void initmatrix(TSMatrix &a,ElemType a1[][N])
{
a.mu=N;
a.nu=N;
a.tu=0;
for(int i=1;i<=a.mu;i++)
for(int j=1;j<=a.nu;j++)
{
if(a1[i-1][j-1]!=0)
{
a.tu++;
a.data[a.tu].i=i;
a.data[a.tu].j=j;
a.data[a.tu].e=a1[i-1][j-1];
}
}
}
void printmatrix(TSMatrix a)
{
a.tu=1;
for(int i=1;i<=a.mu;i++)
{
for(int j=1;j<=a.nu;j++)
{
if(a.data[a.tu].i==i&&a.data[a.tu].j==j)
{
printf("%d ",a.data[a.tu++].e);
}
else
printf("0 ");
}
printf("\n");
}
}
int main()
{
ElemType a1[N][N]= {{1,0,3,0},{0,1,0,0},{0,0,1,0},{0,0,1,1}};
TSMatrix M1,T1; //这里用的是第一个三元组表和第一个转置函数,暂时没用带行连接信息的三元组表
initmatrix(M1,a1); //初始化,把二维数组转换成非零三元组表
//printmatrix(M1); //看一看转置前的样子
TransposeSMatrix(M1,T1);
printmatrix(T1); //输出转置后的矩阵
}