严蔚敏视频 笔记14
Status FastTransposeSMatrix(TSMatrix M,TSMatrix &T) {
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) ++num[M.data[t].j]; // 求M中每一列含非零元个数
cpot[1]=1;
for(col=2;col<=M.nu;++col)
cpot[col]=cpot[col-1]+num[col-1];
for(p=1;p<=M.tu;++p) { // 转置矩阵元素
col=M.data[p].j; q=cpot[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; ++cpot[col];}
}
}
return OK;
}
三元组顺序表——有序的双下标法
特点是非零元在表中按行序有序存储,便于进行依行顺序处理的矩阵运算
而随机存取某一行中非零元则需从头开始进行查找
二、行逻辑链接的顺序表
增加一数据成员rpos
#define MAXMN 500
typedef struct {
Triple data[MAXSIZE+1];
int rpos[MAXMN+1];
int mu,nu,tu;
} RLSMatrix; // 行逻辑链接顺序表类型
矩阵乘法
for(i=1;i<=m1;++i)
for(j=1;j<=n2;++j) {
Q[i][j]=0;
for(k=1;k<=n1;++k)
Q[i][j]+=M[i][k]+N[k][j];
}
时间复杂度为:O(m1*n2*n1)
Q=M*N过程:
Q初始化;
if Q可能是非零矩阵 { // 逐行求积
for(arow=1;arow<=M.mu;++arow) {
// 处理M的每一行
ctemp[]=0; // 累加器清零
计算Q中第arow行的积并存入ctemp[]中;
将ctemp[]中非零元压缩存储到Q.data;
}
}
Status MultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q) {
if(M.nu!=N.mu) return ERROR;
Q.mu=M.mu; Q.nu=N.nu; tu=0;
if(M.tu*N.tu!=0) {
for(arow=1;arow<=M.mu;++arow) { // 处理M的每一行
ctemp[]=0; // 当前行各元素累加器清零
Q.rpos[arow]=Q.tu+1;
for(p=M.rops[arow];p<M.rpos[arow+1];++p) { // 对当前行中每一个非零元
brow=M.data[p].j; // 找到对应元在N中的行号
if(brow<N.nu) t=N.rpos[brow+1];
else t=N.tu+1;
for(q=N.rpos[brow];q<t;++q) {
ccol=N.data[q].j; // 乘积元素在Q中列号
ctemp[ccol]+=M.data[p].e*N.data[q].e;
}
}
// 求得Q中第crow(=arow)行的非零元
for(ccol=1;ccol<=Q.nu;++ccol) // 压缩存储该行非零元
if(ctemp[ccol]) {
if(++Q.tu>MAXSIZE) return ERROR;
Q.data[Q.tu]={arow,ccol,ctemp[ccol]};
}
}
}
return OK;
}
时间复杂度分析
累加器初始化 O(M.mu*N.nu)
求Q的所有非零元 O(M.tu*N.tu/N.mu)
进行压缩存储 O(M.mu*N.nu)
相加就是总的时间复杂度
假设M为m行n列 N为n行p列的稀疏矩阵
算法时间复杂度相当于O(m*p)