行逻辑连接顺序表
采用一位三元结构体组记录的每一个元素在矩阵中的具体位置,采用一维数组记录每行第一个非元素的位置,具有记录行数,列数和非元素总个数的结构体成员变量。
算法思想
逐行求积,每次处理一行,设立一个一维数组ctemp对应乘积结果中的对应行元素构成的数组。
将前乘矩阵M当前行的非0元素找到对应在后乘矩阵N中的对应行,依次去乘其行中每一列的非0元素,然后累加到ctemp对应的元素的位置上。
每行运算结束进行压缩存储到矩阵Q中。
注意事项
本示例中将矩阵的行号和列号与所用数据结构对应,因此三元顺序组和储存行信息的数组下标为0的位置属于浪费位置,可通过修改代码中部分变量的值更正。
以下为可运行源码,内含例子验证正确性。
#include <stdio.h>
const int MAXSIZE = 100;//最多非0元素个数
const int MAXRC = 100;//矩阵最多行数
typedef int ElemType;
typedef struct{
int i,j;
ElemType e;
}Triple;
typedef struct{
Triple data[MAXSIZE+1];//非0三元组表
int rpos[MAXRC+1];//各行第一个非0元的位置表
int mu,nu,tu;//矩阵行数、列数与非0元素个数
}RLSMatrix;
//行逻辑连接的矩阵M*N算法函数
int MultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix &Q){
int ccol=0;
//行累加器
//可运算性判断
if(M.nu!=N.mu)
return -1;
//Q的初始化
Q.mu=M.mu;
Q.nu=N.nu;
Q.tu=0;
//Q为非0矩阵才有运算必要
if(M.tu*N.tu!=0)
{
//当前处理的M的行标
int arow;
//按行处理,arow即是前乘矩阵M的行号也是结果矩阵Q的行号
for(arow=1;arow<=M.mu;++arow) {
//行元素累加器清0
int ctemp[M.nu]={0};
//每计算 一行设置当前行的第一个非0元素位置为之前行所有非0 元素之和+1
Q.rpos[arow]=Q.tu+1;
//当前行的下一行第一个非0元素在M.data中的位置,如果是最后一行取所有的非0元素之和+1
int tp=0;
if(arow<M.mu)
tp=M.rpos[arow+1];
else
{
tp=M.tu+1;
}
int p=0;
int q=0;
int t=0;
//对当前行的每一个非0元素处理 计算其对应的位置乘积和
int brow=0;
for(p=M.rpos[arow];p<tp;++p)
{
//找到该元素对应的N的行号
brow = M.data[p].j;
//取找到的N对应行下一行第一个元素的位置,如果是最后一行取所有的非0元素之和+1
if(brow<N.mu)
t=N.rpos[brow+1];
else
t=N.tu+1;
//N对应行位置上的元素与M当前位置元素相乘,累加进入ctemp行累加器对应位置
for(q=N.rpos[brow];q<t;++q)
{
ccol=N.data[q].j;
ctemp[ccol]+=M.data[p].e*N.data[q].e;
}
}
//累加器上对应位置压缩存储
for(ccol=1;ccol<=Q.nu;++ccol)
{
if(ctemp[ccol]){
if(++Q.tu>MAXSIZE)
return -1;
Q.data[Q.tu].i=arow;
Q.data[Q.tu].j=ccol;
Q.data[Q.tu].e=ctemp[ccol];
}
}
}
Q.rpos[arow]=Q.tu+1;
}
return 1;
}
int main(){
RLSMatrix M={{{0,0,0},{1,1,3},{1,4,5},{2,2,-1},{3,1,2}},
{0,1,3,4,5},
3,4,4};
RLSMatrix N={{{0,0,0},{1,2,2},{2,1,1},{3,1,-2},{3,2,4}},
{0,1,2,3,5},
4,2,4};
RLSMatrix M0={{{0,0,0},{1,1,1},{1,2,2},{1,3,3},{2,1,4},{2,2,5},{2,3,6}},
{0,1,4,0},
2,3,6};
RLSMatrix N0={{{0,0,0},{1,1,1},{1,2,2},{2,1,3},{2,2,4},{3,1,5},{3,2,6}},
{0,1,3,5,0},
3,2,6};
RLSMatrix Q;
MultSMatrix(M0,N0,Q);
for(int i=1;i<=Q.tu;i++)
printf("%4d%4d%4d\n%5d\n%5d%5d%5d\n%5d\n\n",Q.data[i].i,Q.data[i].j,Q.data[i].e,Q.rpos[i],Q.mu,Q.nu,Q.tu,i);
}