c语言版数据结构(奇迹冬瓜)-数组和广义表(稀疏矩阵的乘法)

//-------矩阵的乘法---------
/*
假设题目:
   3  0  0  5      0  2      0  6 
M= 0 -1  0  0   N= 1  0   Q=-1  0   Q=M*N
   2  0  0  0     -2  4      0  4
                   0  0
(表1)

非零元三元表:
M:             N:             Q:             i表示行 j表示列 e表示非零元的数据
----------     ----------     ----------
i   j   e      i   j   e      i   j   e
----------     ----------     ----------
1   1   3      1   2   2      1   2   6
1   4   5      2   1   1      2   1  -1
2   2  -1      3   1  -2      3   2   4
3   1   2      3   2   4
(表2)

rpos表(各行第一个非零元位置):
M:                 N:                      Q:               row表示行 rpos表示每行第一个非零元是第几个非零元
----------------   --------------------    -------------
row   1   2   3    row   1   2   3   4     row  1  2  3
----------------   --------------------    -------------
rpos  1   3   4    rpos  1   2   3   5     rpos 1  2  3
(表3)

n1
∑M(i,k)*N(k,j)   1=<i<=m1   1=<j<=n2   //矩阵求积公式
k=1

*/

#include<stdio.h>
#include<stdlib.h>
//宏定义

#define MAXSIZE 4  
#define MAXRC 4
#define ERROR 0
#define OK 1

typedef int Status;

typedef struct
{
	int i,j;       //i,j表示行与列
	int e;         //e表示在该位置的数据
}Triple;           //三元组模拟表1

typedef struct
{
	Triple date[MAXSIZE+1];  //非零三元组表
	int rops[MAXRC+1];      //各行的第一个非零元
	int mu,nu,tu;           //矩阵的行,列,非零元的个数
}RLSMatrix;                 //矩阵的抽象

Status MultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix *Q);//计算矩阵乘积的函数

void main()
{
	RLSMatrix M,N,Q;
	int k;

	M.date[1].i=1;
	M.date[1].j=1;
	M.date[1].e=3;
	M.date[2].i=1;
	M.date[2].j=4;
	M.date[2].e=5;
	M.date[3].i=2;
	M.date[3].j=2;
	M.date[3].e=-1;
	M.date[4].i=3;
	M.date[4].j=1;
	M.date[4].e=2;
	M.rops[1]=1;
	M.rops[2]=2;
	M.rops[3]=4;
	M.mu=3;
	M.nu=4;
	M.tu=4;                                  //初始化M矩阵的各项属性

	N.date[1].i=1;
	N.date[1].j=2;
	N.date[1].e=2;
	N.date[2].i=2;
	N.date[2].j=1;
	N.date[2].e=1;
	N.date[3].i=3;
	N.date[3].j=1;
	N.date[3].e=-2;
	N.date[4].i=3;
	N.date[4].j=2;
	N.date[4].e=4;
	N.rops[1]=1;
	N.rops[2]=2;
	N.rops[3]=3;
	N.rops[4]=5;
	N.mu=4;
	N.nu=2;
	N.tu=4;                              //初始化N矩阵的各项矩阵

	MultSMatrix(M,N,&Q);

	printf("Q:\n-------------------\ni\tj\te\n-------------------\n");
	for(k=1;k<=Q.tu;k++)
	{
		printf("%d\t%d\t%d\n",Q.date[k].i,Q.date[k].j,Q.date[k].e);
	}

	getchar();
	getchar();
}

Status MultSMatrix(RLSMatrix M,RLSMatrix N,RLSMatrix *Q)
{
	int arow,ccol,ctemp[4];  //Q矩阵的行,列,以及乘积的累加
	int tp,p,q,t,i,brow;     //需要用到的中间量
	Q->mu=M.mu;
	Q->nu=N.nu;
	Q->tu=0;                 //Q矩阵的初始化
	if(M.nu!=N.mu)
	{
		return ERROR;        //根据矩阵的性质判断两个矩阵能否相乘,如不能返回ERROR
	}
	if(0!=M.tu*N.tu)         //判断Q是否为0矩阵,不是则继续
	{
		for(arow=1;arow<=M.mu;arow++)
		{
			for(i=0;i<4;i++)
			{
				ctemp[i]=0;      //初始化累加器,用于存M的某个行元素与N的整列元素的乘积和(参考矩阵的乘法)
			}
			Q->rops[arow]=Q->tu+1;   //生成Q的rops表(参考表3,用于方便的定位和计算)
			if(arow<M.mu)
			{
				tp=M.rops[arow+1];    //tp定位到要累乘行的下一行
			}
			else
			{
				tp=M.tu+1;
			}
			for(p=M.rops[arow];p<tp;p++)   //遍历第arow行的矩阵元素
			{
				brow=M.date[p].j;          //∑M(i,k)*N(k,j) M的矩阵的列和N矩阵的行相同.
				if(brow<N.mu)
				{
					t=N.rops[brow+1];
				}
				else
				{
					t=N.tu+1;              //原理同M矩阵的搜寻一样
				}
				for(q=N.rops[brow];q<t;q++) 
				{
					ccol=N.date[q].j;
					ctemp[ccol]+=M.date[p].e*N.date[q].e; //乘积和
				}
			}
			for(ccol=1;ccol<=Q->nu;ccol++)
			{
				if(ctemp[ccol])
				{
					if(++Q->tu>MAXSIZE)
					{
						return ERROR;        //检查是否溢出
					}
					Q->date[Q->tu].i=arow;
					Q->date[Q->tu].j=ccol;
					Q->date[Q->tu].e=ctemp[ccol];
				}
			}
		}
	}
	return OK;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值