}
}
以上主要设计思想为:
此功能由函数multi()实现。
当用户选择该功能,系统提示输入要进行相乘的两个矩阵的详细信息。
然后检测两者是否可以相乘,如果不能,则重新初始化第二个矩阵。
先对矩阵B进行逐行处理,先求得累计求和的中间结果(C的每一行),然后再压缩存储到c.data中去,最后得到结果。
第四章设计理论分析方法
4.1算法一:
矩阵转置
转置运算时一种最简单的矩阵运算,对于一个m*n的矩阵M,他的转置矩阵T是一个n*m的矩阵,且T(i,j)=M(j,i),1<=i<=n,1<=j<=m。
显然,一个稀疏矩阵的转置矩阵仍然是稀疏矩阵。
(1)将矩阵的行列值相互交换;
(2)将每个三元组中的i和j相互调换;(3)重排三元组之间的次序便可实现矩阵的转置。
一般矩阵转置算法为
for(col=1;col<=nu;++col)
for(row=1;row<=mu;++row)
T[col][row]=M[row][col];
按照a.data中三元组的次序进行转置,并将转置后的三元组置入b中恰当的位置。
在此,需要附设num和cpot两个向量。
Num[col]表示矩阵M中第col列中非零元的个数,cpot[col]指示M中第col列的第一个非零元在b.data中的恰当位置。
cpot[1]=1
cpot[col]=cpot[col-1]+num[col-1]2<=col<=a.nu
这就是快速转置。
4.2算法二:
矩阵加法
稀疏矩阵使用三元组存储,则运算时只需考虑非零元的值即可。
两个矩阵相加
首先必须保证M.mu=N.mu&&M.nu=N.nu即同行同列的矩阵才能相加。
for(k=1;k<=M.tu;k++)
for(i=1;i<=N.tu;i++)
if(M.data[k].i==N.data[i].i&&
M.data[k].j==N.data[i].j)
Q.data[count].e=M.data[k].e+N.data[i].e;
flag[i]=true;
如果非零元位置一样就直接相加
if(i>N.tu)
Q.data[count].e=M.data[k].e;
如果没有找到与M非零元位置一样的元素就直接把M中的非零元赋值给矩阵Q。
for(k=1;k<=N.tu;k++)
if(!
flag[k])
Q.data[count].e=N.data[k].e;
如果N中的元素没有被查找,则直接把N中的非零元赋值给矩阵Q。
4.3算法三:
矩阵乘法
矩阵乘法采用“带行信息”的三元组存储。
经典算法如下:
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[j][k]*N[k][j];
}
稀疏矩阵相乘前提:
M.nu=N.mu
大致步骤描述如下:
Q初始化;
If(Q是非零矩阵)
{//逐行求积
for(arow=1;arrow<=M.mu;++arow)
{//处理M的每一行
ctemp[]=0;//累加器清零
计算Q中第arow行的积并存入ctemp[]中;
将ctemp[]中非零元压缩存储到Q.data;
}
}
第五章程序调试
整个程序主要运用了矩阵运算的规则,利用创建三元组表,分析数据,行列是否匹配,稀疏矩阵的转置,稀疏矩阵的相加,稀疏矩阵的相乘。
(1)稀疏矩阵的转置
图5.1
(2)稀疏矩阵的加法
图5.2
(3)稀疏矩阵的乘法:
图5.3
第六章心得体会
通过此次课程设计,使我更加扎实的掌握了有关稀疏矩阵方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。
实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。
过而能改,善莫大焉。
在课程设计过程中,不断发现错误,不断改正,不断领悟,不断获取。
最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。
这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师和同学的指导下,终于游逆而解。
在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可!
参考文献
[1]谭浩强著.C程序设计(第三版)[M].:
清华大学,2009.5
[2]严蔚敏、吴伟民主编《数据结构(C语言版)》[M].清华大学2004.11
[3].建学等编著《数据结构课程设计案例精编(用C/C++描述)》[M],清华大学2007.2
[4].殷人昆主编《数据结构:
用面向对象方法与C++语言描述》[M], 清华大学2007.6