稀疏矩阵的运算.docx

上传人:b****6 文档编号:4017612 上传时间:2022-11-27 格式:DOCX 页数:26 大小:350.37KB
下载 相关 举报
稀疏矩阵的运算.docx_第1页
第1页 / 共26页
稀疏矩阵的运算.docx_第2页
第2页 / 共26页
稀疏矩阵的运算.docx_第3页
第3页 / 共26页
稀疏矩阵的运算.docx_第4页
第4页 / 共26页
稀疏矩阵的运算.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

稀疏矩阵的运算.docx

《稀疏矩阵的运算.docx》由会员分享,可在线阅读,更多相关《稀疏矩阵的运算.docx(26页珍藏版)》请在冰豆网上搜索。

稀疏矩阵的运算.docx

稀疏矩阵的运算

数据结构课程设计

稀疏矩阵的运算

学生姓名:

学号:

指导教师:

完成日期:

目录:

1、分析问题和确定解决方案…………………………3

1.1问题描述……………………………3

1.2输入的形式和输入值的范围……………………3

1.3输出的形式………………………………3

1.4程序所能达到的功能……………………………3

1.5测试数据………………………………3

1.6确定解决方案………………………………4

1.7所有抽象数据类型的定义……………………………4

2、详细设计……………………………5

2.1稀疏矩阵加法运算思路……………………………5

2.2稀疏矩阵减法运算思路………………………………7

2.3稀疏矩阵转置运算思路………………………………9

2.4创建稀疏矩阵………………………………11

3、系统调试与测试……………………………12

3.1程序的菜单界面………………………………12

3.2实现加法运算………………………………12

3.3实现减法运算………………………………13

3.4实现转置运算………………………………14

4、结果分析……………………………………15

4.1、算法的时空分析………………………………15

4.2、经验和体会………………………………15

5、参考文献………………………………15

1、分析问题和确定解决方案

1.1问题描述

稀疏矩阵是指那些多数元素为零的矩阵。

利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。

实现一个能进行稀疏矩阵基本运算的运算器。

用三元组实现稀疏矩阵的相加、相减,转置;

1.2输入的形式和输入值的范围

以三元组的形式输入,首先应输入矩阵的行数和列数,并判别给出的两个矩阵的行、列数对于所要求作的运算是否相匹配。

可设矩阵的行数和列数均不超过20;

例如:

输入的三元组为:

((1,1,10),(2,3,9),(3,1,-1))其对应的稀疏矩阵为:

1.3输出的形式

运算结果的矩阵以通常的阵列形式输出;

1.4程序所能达到的功能

该程序可以实现以三元组形式输入两个矩阵,求出两个矩阵的和、差、转置;并可根据输入的矩阵的行列数不同判别是否可以进行相加、减、转置,并重新输入正确的矩阵;

1.5测试数据

测试的数据及其结果如下:

矩阵M矩阵N矩阵Q

加法:

+

=

减法:

-

=

转置:

->

1.6确定解决方案

进入运算器界面后选择要实行的操作,按1实现矩阵相加,调用函数AddRLSMatrix,若输入的两个矩阵行列数不相等,则提示输入错误,重新输入矩阵进行加法运算;按2实现矩阵相减,若输入的两个矩阵行列数不相等,则提示输入错误,重新输入矩阵进行减法运算;按3实现矩阵的转置;按4退出程序;

以加法为例实现运算过程,如下:

(稀疏矩阵的和为Q)

第一个稀疏矩阵M的三元组为((1,1,10),(2,3,9),(3,1,-1))

第二个稀疏矩阵N的三元组为((2,3,-1),(3,1,1),(3,3,-3))

M的第一个三元组(1,1,10)与N的第一个三元组(2,3,-1)比较,因行数1<2则Q得到第一个三元组(1,1,10);M的第二个三元组与N的第一个三元组比较,因对应行列数相等则9+(-1)=8,次行列数就是Q的行列数即得到Q的第二个三元组为(2,3,8);M第三个三元组(3,1,-1))与N的第二个三元组进行比较,因对应行列数相等,且1+(-1)=0,则不进行相加;而此时只有N的第三个三元组(3,3,-3)符合条件,则Q得到第三个三元组(3,3,-3);最终结果为

((1,1,10),(2,3,8),(3,3,-3))

1.7所有抽象数据类型的定义

 以顺序存储结构来表示三元组表,则可得到稀疏矩阵的一种压缩存储方式——三元组顺序表。

/*稀疏矩阵的三元组顺序表存储表示*/

#defineMAXSIZE20//假设非零元个数的最大值为20

typedefstruct

{inti,j;//该非零元的行下标和列下标

ElemTypee;//该非零元数值

}Triple;

typedefstruct

{Tripledata[MAXSIZE+1];//非零三元组表,data[0]未用

intmu,nu,tu;//矩阵的行数(<20)、列数(<20)和非零元个数

}RLSMatrix;

在此,data域中表示非零元得三元组是以行序为主序顺序排列的,这样有利于进行某些矩阵运算。

抽象数据类型稀疏矩阵的定义如下:

ADTSparseMatrix{

数据对象:

D={aij|i=1,2,3,…,m;j=1,2,…,n;

Aij(-ElemSet,m和n分别称为矩阵的行数和列数}

数据关系:

R={Row,Col}

基本操作:

CreateSMatrix(&M);

操作结果:

创建稀疏矩阵M。

PrintSMatrix(M);

初始条件:

稀疏矩阵M存在。

操作结果:

输出稀疏矩阵M。

AddRLSMatrix(M,N,&Q);

初始条件:

稀疏矩阵M和N的的行数和列数对应相等。

操作结果:

求稀疏矩阵的和Q=M+N。

SubRLSMatrix(M,N,&Q);

初始条件:

稀疏矩阵M和N的的行数和列数对应相等。

操作结果:

求稀疏矩阵的差Q=M-N。

TransposeSMatrix(M,&T);

}ADTSpareMatrix

此流程表示的是主程序的流程以及各程序模块之间的层次(调用)关系。

稀疏矩阵运算器

2、详细设计

2.1稀疏矩阵的加法运算思路

比较满足条件(行数及列数都相同的两个矩阵)的两个稀疏矩阵中不为0的元素的行数及列数(即i与j),将i与j都相等的前后两个元素值e相加,保持i,j不变储存在新的三元组中,不等的则分别储存在此新三元组中。

最后得到的这个新三元组表就是两个矩阵的和矩阵的三元组表。

其算法如下:

voidAddRLSMatrix(RLSMatrixM,RLSMatrixN,RLSMatrix*Q)//稀疏矩阵相加

{

intp,q,k=1;

if(M.mu!

=N.mu||M.nu!

=N.nu)

{

printf("你的输入不满足矩阵相加的条件!

\n");

exit

(1);

}

Q->mu=M.mu;Q->nu=M.nu;

for(p=1,q=1;p<=M.tu&&q<=N.tu;)

{

if(M.data[p].i==N.data[q].i)

{

if(M.data[p].j==N.data[q].j)

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e+N.data[q].e;

p++;q++;k++;

}

elseif(M.data[p].j

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;p++;

}

elseif(M.data[p].j>N.data[q].j)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=N.data[q].e;

k++;p++;

}

}

elseif(M.data[p].i

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;p++;

}

elseif(M.data[p].i>N.data[q].i)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=N.data[q].e;

k++;q++;

}

}

if(p!

=M.tu+1)

for(;p<=M.tu;p++)

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;

}

if(q!

=N.tu+1)

for(;q<=N.tu;q++)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=N.data[q].e;

k++;

}

}

2.2稀疏矩阵相减的算法思路

此思路与稀疏矩阵相加的算法思路相同,其算法如下:

voidSubRLSMatrix(RLSMatrixM,RLSMatrixN,RLSMatrix*Q)//稀疏矩阵相减

{

intp,q,k=1;

if(M.mu!

=N.mu||M.nu!

=N.nu)

{

printf("你的输入不满足矩阵相减的条件!

\n");

exit

(1);

}

Q->mu=M.mu;Q->nu=M.nu;

for(p=1,q=1;p<=M.tu&&q<=N.tu;)

{

if(M.data[p].i==N.data[q].i)

{

if(M.data[p].j==N.data[q].j)

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e-N.data[q].e;

p++;q++;k++;

}

elseif(M.data[p].j

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;p++;

}

elseif(M.data[p].j>N.data[q].j)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=-N.data[q].e;

k++;p++;

}

}

elseif(M.data[p].i

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;p++;

}

elseif(M.data[p].i>N.data[q].i)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=-N.data[q].e;

k++;q++;

}

}

if(p!

=M.tu+1)

for(;p<=M.tu;p++)

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;

}

if(q!

=N.tu+1)

for(;q<=N.tu;q++)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=-N.data[q].e;

k++;

}

}

2.3稀疏矩阵转置的算法思路

转置运算是一种简单的矩阵运算。

对于一个m×n的矩阵M,它的转置矩阵T是一个n×m的矩阵,且T(i,j)=M(j,i),1≤i≤n,1≤j≤m。

voidTransposeSMatrix(RLSMatrix*M,RLSMatrix*N)//实现矩阵的转置

{

intq,col,p;

N->mu=M->nu;

N->nu=M->mu;

N->tu=M->tu;

if(N->tu)

{

q=1;

for(col=1;col<=M->tu;col++)

for(p=1;p<=M->tu;p++)

if(M->data[p].j==col)

{

N->data[q].i=M->data[p].j;

N->data[q].j=M->data[p].i;

N->data[q].e=M->data[p].e;

++q;

}

}

}

2.4创建稀疏矩阵

以三元组表的形式输入创建稀疏矩阵

其算法如下:

voidCreateSMatrix(RLSMatrix*T)//输入创建稀疏矩阵

{

intk;

printf("\n请输入矩阵行数、列数及非零元个数:

");

scanf("%d%d%d",&T->mu,&T->nu,&T->tu);

printf("\n");

if(T->tu>MAXSIZE||T->mu>21)

{

printf("非零个数超出定义范围!

出错!

");

exit(0);

}

for(k=1;k<=T->tu;k++)

{

printf("请输入第%d个非零元素的行数,列数及其值:

",k);

scanf("%d%d%d",&T->data[k].i,&T->data[k].j,&T->data[k].e);

}

}

voidAddRLSMatrix(RLSMatrixM,RLSMatrixN,RLSMatrix*Q)//稀疏矩阵相加

{

intp,q,k=1;

if(M.mu!

=N.mu||M.nu!

=N.nu)

{

printf("你的输入不满足矩阵相加的条件!

\n");

exit

(1);

}

Q->mu=M.mu;Q->nu=M.nu;

for(p=1,q=1;p<=M.tu&&q<=N.tu;)

{

if(M.data[p].i==N.data[q].i)

{

if(M.data[p].j==N.data[q].j)

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e+N.data[q].e;

p++;q++;k++;

}

elseif(M.data[p].j

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;p++;

}

elseif(M.data[p].j>N.data[q].j)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=N.data[q].e;

k++;p++;

}

}

elseif(M.data[p].i

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;p++;

}

elseif(M.data[p].i>N.data[q].i)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=N.data[q].e;

k++;q++;

}

}

if(p!

=M.tu+1)

for(;p<=M.tu;p++)

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;

}

if(q!

=N.tu+1)

for(;q<=N.tu;q++)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=N.data[q].e;

k++;

}

}

 

3、系统调试与测试

3.1程序的菜单界面如下:

 

3.2实现加法运算:

3.3实现减法运算:

 

3.4实现转置运算:

 

当在调试程序过程中遇到有错误的时候,先试着进行调试,找出不应该有得小错误,同时参照课本的算法思路对错误的语句进行分析,也上网找XX查询,以得到无错误的程序,更重要的是向别人请教。

 

4、结果分析

4.1时间复杂度的分析

a)加法运算

由于两矩阵行列相等,故时间复杂度为O(行*列)

b)减法运算

由于两矩阵行列相等,故时间复杂度为O(行*列)

c)转置运算

时间复杂度是O(列*非零元的个数)

4.2心得体会

虽然一直以来我不怎么喜欢数据结构这门课,但是它已经是我的一门课程,我就必须学好它,曾经在编程上遇到过很多困难,编了一学期的程序,有时会因为编出作业题目而又高兴几天,有时会因编不出程序而失落几天,总之,我喜欢编程的过程,包括与同学交流,上网XX,从中学到了很多。

5、参考文献

1、《数据结构》(c语言描述),严蔚敏编著,清华大学出版社

2、《数据结构题集》,严蔚敏编著,清华大学出版社

附源代码:

#include

#include

#defineMAXSIZE20

#defineMAXRC20

typedefstruct//稀疏矩阵的三元组顺序表存储表示

{inti,j;//该非零元的行下标和列下标

inte;

}Triple;

typedefstruct

{

Tripledata[MAXSIZE+1];//非零元三元组表,data[0]未用

intrpos[MAXRC+1];//各行第一个非零元的位置表

intmu,nu,tu;//矩阵的行数列数和非零元的个数

}RLSMatrix;

voidCreateSMatrix(RLSMatrix*T)//输入创建稀疏矩阵

{

intk;

printf("\n请输入矩阵行数、列数及非零元个数:

");

scanf("%d%d%d",&T->mu,&T->nu,&T->tu);

printf("\n");

if(T->tu>MAXSIZE||T->mu>21)

{

printf("非零个数超出定义范围!

出错!

");

exit(0);

}

for(k=1;k<=T->tu;k++)

{

printf("请输入第%d个非零元素的行数,列数及其值:

",k);

scanf("%d%d%d",&T->data[k].i,&T->data[k].j,&T->data[k].e);

}

}

voidAddRLSMatrix(RLSMatrixM,RLSMatrixN,RLSMatrix*Q)//稀疏矩阵相加

{

intp,q,k=1;

if(M.mu!

=N.mu||M.nu!

=N.nu)

{

printf("你的输入不满足矩阵相加的条件!

\n");

exit

(1);

}

Q->mu=M.mu;Q->nu=M.nu;

for(p=1,q=1;p<=M.tu&&q<=N.tu;)

{

if(M.data[p].i==N.data[q].i)

{

if(M.data[p].j==N.data[q].j)

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e+N.data[q].e;

p++;q++;k++;

}

elseif(M.data[p].j

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;p++;

}

elseif(M.data[p].j>N.data[q].j)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=N.data[q].e;

k++;p++;

}

}

elseif(M.data[p].i

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;p++;

}

elseif(M.data[p].i>N.data[q].i)

{

Q->data[k].i=N.data[q].i;

Q->data[k].j=N.data[q].j;

Q->data[k].e=N.data[q].e;

k++;q++;

}

}

if(p!

=M.tu+1)

for(;p<=M.tu;p++)

{

Q->data[k].i=M.data[p].i;

Q->data[k].j=M.data[p].j;

Q->data[k].e=M.data[p].e;

k++;

}

if(q!

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 政史地

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1