//-------矩阵的乘法---------
/*
假设题目:
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;
}
c语言版数据结构(奇迹冬瓜)-数组和广义表(稀疏矩阵的乘法)
最新推荐文章于 2021-09-15 08:27:00 发布