行逻辑连接的顺序表实现稀疏矩阵乘法

 

行逻辑连接顺序表

采用一位三元结构体组记录的每一个元素在矩阵中的具体位置,采用一维数组记录每行第一个非元素的位置,具有记录行数,列数和非元素总个数的结构体成员变量。

算法思想

逐行求积,每次处理一行,设立一个一维数组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);
	 
}

 

 

 

 

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NineKit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值