ImageVerifierCode 换一换
格式:DOCX , 页数:32 ,大小:196.39KB ,
资源ID:3388858      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3388858.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(矩阵的加法运算问题数据结构与算法课程设计报告.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

矩阵的加法运算问题数据结构与算法课程设计报告.docx

1、矩阵的加法运算问题数据结构与算法课程设计报告合肥学院计算机科学与技术系课程设计报告 2009 2010 学年第 二 学期课程数据结构与算法课程设计名称矩阵的加法运算问题学生姓名胡九铭学号0804012039专业班级计算机科学与技术08级(2)班指导教师王昆仑 张贯虹 2010 年 6 月一、问题分析和任务定义1、问题分析此程序需要完成如下要求:设计十字链表表示稀疏矩阵,并实现矩阵的加法运算。并且要求能够要检查有关运算的条件,并对错误的条件产生报警。2、(1)设计函数建立稀疏矩阵。(2)设计函数输出稀疏矩阵的值。(3)构造函数进行两个稀疏矩阵相加,(4)构造函数进行两个稀疏矩阵相加时是否能够符合

2、运算要求,即检查有关运算的条件,并对错误的条件产生错误警报。(5)登录函数,即需要口令才可以登录并使用计算器(6)退出系统3、原始数据的输入和输出格式由于该问题是关于矩阵的运算方面的内容,所以输入时是对矩阵中的非零元分别进行插入矩阵中,输入格式是:行、列、元素值,以数字的形式输入。输出时,为了能更易于用户的观察和比较所以选用矩阵表的格式输出,这可以更加方便看出结果的正确与否,也有利于在编写程序的时候修改和改善程序的源代码。4、算法应能实现的功能 该算法应能实现:正确的用十字链表的存储结构建立数个稀疏矩阵;正确的输出用户建立的矩阵;能进行数个矩阵的相加运算;能对加法运算的运算条件进行判断并能对其

3、产生报警提示。5、该问题测试用例 (a)两个行列分别相同的矩阵 0 0 0 9 0 0 5 0 0 + 5 2 0 0 0 9 0 0 0预测结果: 9 0 0 = 10 2 0 0 0 9(b)两个行列数不相同的矩阵 3 0 0 0 0 0 0 0 0 6 0 6 0 0 + 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0预测结果: 输出:不能进行加法运算,矩阵的行数和列数应分别相同!(c)两个以上的矩阵相加 0 0 0 0 0 1 0 0 0 0 0 6 0 0 0 0 -3 0 0 0 5 0 3 0 0 + 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0

4、 0 0 0 0 0 0 0 0 0 0 0 0 5 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 5 0 0 0 预测结果: 1 0 0 5 0 2 3 0 0 0 = 6 0 3 0 0 0 0 0 0 00 5 0 0 0 二、数据结构的选择和概要设计1、主界面设计:为了实现对稀疏矩阵的多种算法功能的管理,首先设计一个含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户交互式使用本系统。本系统登录菜单运行界面如图1-1所示图1-1除了登录矩阵计算器菜单之外,还有计算器的选项菜单,如图1-2所示图1-22、存储结构设计:本系统采用十字链表结构存储稀疏矩阵的具

5、体信息。其中:全部结点的信息用头结点为指针数组的链表存储;每个结点里面包含行号(i),列号(j)和对应的数值(v),它们是整型数据,还有两个指针cptr、rptr分别是行指针域和列指针域,属于node结构体。全部的信息用结构体(CrossList)包含,包括指针数组(rhead和chead)和总共的行数(m),列数(n)以及非零元素的个数(t)。3. 系统功能设计:本系统要完成稀疏矩阵的加法,就需要建立稀疏矩阵,则用Creat_CrossList()实现,然后要依次读取信息,即向Creat_CrossList()创建的空链表中插入结点,就是从键盘读取信息,行号,列号以及非零元素的值,这需要通过

6、函数Insert_CrossList()来完成这个工作。在该课程设计中,最主要的就是实现矩阵的加法,即矩阵A+B,该功能通过调用函数Matrixpuls_CrossList();来实现的。 要输出通过输出函数 Display_CrossList();来完成。 但是在程序执行的过程中,调用相加函数之前,需要判断两个矩阵A与B是否符合矩阵相加的条件。最后就是需要退出程序的操作,可以根据功能菜单选择进行操作,就可以退出程序。4、模块设计:本程序包含2个模块:主程序模块和各功能实现模块。调用关系如图1-3所示。图1-3 模块调用示意图5、系统子程序及功能设计(1) CrossList *Creat_C

7、rossList() /创建矩阵(2) CrossList *Insert_CrossList(CrossList *M) /往矩阵中插入结点信息(3) void Dispaly_CrossList(CrossList *M) /输出矩阵信息(4) CrossList *Matrixpuls_CrossList(CrossList *A,CrossList *B) /矩阵相加(5) int Judge_CrossList(CrossList *A,CrossList *B) /判断矩阵是否符合相加条件(6) void Login_Menu() /登录菜单(7) void Login_Pcmd(

8、) /登录函数(8) void main() /主函数,设置窗口模式和窗口标题,以及调用各个子函数(9) Select_Menu() /计算器功能选择菜三、详细设计和编码1、数据类型的定义/结点类型typedef struct nodeint i,j,v; /元素的行标、列标、值域 struct node *rptr,*cptr; /行指针域、列指针域OLNode; /十字链表类型typedef structOLNode *rheadK,*cheadN; /存放行链表及列链表的首地址 int m,n,t; /矩阵的行数、列数、非灵元素个数CrossList; 2系统主要子程序详细设计(1)主程

9、序模块设计及用户工作区模块设计/设置窗口的大小,颜色,标题system(cls);/清屏 system(color 17);/设置窗口的背景颜色 system(mode con cols=60 lines=25);/设置窗口模式 system(title 欢迎使用矩阵加法计算器);/ 设置窗口标题 以后根据程序的提示执行操作,选择自己需要执行的操作(2) 以下是稀疏矩阵操作各子函数的定义:建立稀疏矩阵:输入行数,然后判断行数是否符合要求,即行数是否大于0,若不符合则需要重新输入数据printf(n%c 输入行数:,1); /输入行数 scanf(%d,&(M-m); while(M-mm);

10、输入列数,然后判断列数是否符合要求,即列数是否大于0,若不符合则需要重新输入数据 printf(n%c 输入列数:,1); /输入列数 scanf(%d,&(M-n); while(M-nn);输入非零元素的个数,然后判断个数是否符合要求,即列数是否大于等于0,若不符合则需要重新输入数据 printf(n%c 输入非零元素数个数:,1); /输入非零元素个数 scanf(%d,&(M-t); while(M-tt);判断创建矩阵的行数列数=非零元素的个数,比如5行3列,总共可以存储15个元素,而输入的时候可能会输入的数大于15,比如20,造成无法存储,这就需要重新创建矩阵。while(M-t(

11、M-m*M-n) / printf(n%c 不符合条件.n,1); printf(n); printf(%c 重要提示:输入失败的原因是非零元素的个数 行数 x 列数n,1); printf(n%c 重新输入.,1); printf(n);printf(n);printf(n);printf(n); system(pause);/暂停 system(cls);/清屏 printf(n%c 输入行数:,1); scanf(%d,&(M-m); while(M-mm); printf(n%c 输入列数:,1); scanf(%d,&(M-n); while(M-nn); printf(n%c 输入

12、非零元素数个数:,1); scanf(%d,&(M-t); while(M-tt);输出稀疏矩阵:通过for循环,来输出矩阵中的所有的非零元素的信息for(a=1;am;a+) p=M-rheada; while(p!=NULL) printf(t%c t,1,p-i,p-j,p-v); p=p-rptr; printf(n); 插入结点信息:初始化行链表,列链表为空for(i=1;im;i+) /行链表置空 M-rheadi=NULL; for(i=1;in;i+) /列链表置空 M-cheadi=NULL;向创建的空矩阵中插入结点信息,不符合要求就需要重新输入。比如输入的一个结点的信息的行

13、号、列号大于行数或者列数。printf(n%c 第%d个元素为:,1,h); scanf(%d%d%d,&p-i,&p-j,&p-v); while(p-iM-m|p-jM-n) /判断输入是否符合要求 printf(n%c 重要提示:该元素的行号或者列号超出范围.,1); printf(n); printf(n%c 重新输入第%d个元素:,1,h); scanf(%d%d%d,&p-i,&p-j,&p-v); 将结点插入到行链表的指针数组中,用数组rhead来存储 if(M-rheadp-i=NULL)|(M-rheadp-i-j)(p-j) /当该元素所在的行首地址为空或当前结点的列号比该

14、列行链表中第一个结点的行号小 p-rptr=M-rheadp-i; /将该结点作为首元素结点插入到该行链表中 M-rheadp-i=p; else/查找该行链表中的个结点的列号,将该结点按列号的顺序插入到该行链表中 u=M-rheadp-i; q=M-rheadp-i-rptr; while(q!=NULL) /指针后移找到比待插入结点列号大的元素地址 if(q-jp-j) break; u=q; q=q-rptr; p-rptr=q; /插入结点 u-rptr=p;将结点插入到列链表的指针数组中,用数组chead来存储if(M-cheadp-j=NULL)|(M-cheadp-j-i)(p-

15、i) /根据列号将结点插入到相应的列链表中 p-cptr=M-cheadp-j; /将该结点作为首元素结点插入到该列链表中 M-cheadp-j=p; else u=M-cheadp-j; q=M-cheadp-j-cptr; while(q!=NULL) if(q-ip-j) break; u=q; q=q-cptr; p-cptr=q; u-cptr=p; 矩阵相加函数:令a,b分别指向A和B的第一个行链表i=1a=A-rheadi; /将矩阵A第i行的首地址赋给ab=B-rheadi; /将矩阵B第i行的首地址赋给b并初始化指针acolfor(i=1;in;i+) acoli=A-che

16、adi;逐行比较行链表A-rheadi与B-rheadi上的每一个结点*a和*b,直到链表B-rheadi中所有非0元结点均比较完毕:、若链表A-rheadi已比较完毕,或结点*b的列号小于结点*a的列号,则在链表A-rheadi中插入一个*b的复制结点: if(a=NULL|a-jb-j) /若a地址为空或列号大于b的列号 if(pre=NULL) /a的前驱为空时 A-rheadi=p; /将p插入到该行头结点之前 else pre-rptr=p; /将p插到a结点之前 p-rptr=a; pre=p; /a的前驱变为p结点 同时结点*p也插入到相应的列链表中。、若结点*b的列号大于结点*

17、a的列号,则在链表A-rheadi中查到列号大于*b的列号结点的前驱结点,并插入一个*b的复制结点*p;即若*c的后继结点的列号大于*b的列号,则*p插入到*c后:while(a!=NULL&a-jj) pre=a; a=a-rptr; if(a=NULL|a-jb-j) /若a地址为空或列号大于b的列号 pre-rptr=p; /将p插到a结点之前 p-rptr=a; pre=p;/a的前驱变为p结点 else /否则两结点列号相同 a-v=a-v+b-v;/将两节点数值相加赋给a if(a-v=0) /若相加后为值为0 if(pre=NULL)/a的前驱为空时 A-rheadi=a-rpt

18、r;/将a结点删除 else pre-rptr=a-rptr;/否则,将a的前驱后移一位 p=a;/p指向被删除的结点 a=a-rptr;/a后移一位 if(A-cheadp-j=p) /p指向的结点为所在列的首元素时 A-cheadp-j=p-cptr;/将p从列链表中删除 acolp-j=p-cptr; else /找到p所在列链表的前驱结点 while(acolp-j-cptr!=p) acolp-j=acolp-j-cptr; acolp-j-cptr=p-cptr; /将p从列链表中删除 free(p); /释放p指向结点的空间 else /若相加后为值不为0 pre=a;/pre指

19、向a a=a-rptr; /a后移一位 break;同时,结点*p也插入到相应的列链表中。、若结点*b的列号等于结点*a的列号,将*b结点的值加到*a结点上:if(a!=NULL&a-j=b-j)/如果两结点列号相同 a-v=a-v+b-v; 此时,若a-v!=0;则无需其他操作;否则,在十字链表A中删除该结点。在行链表中删除该结点: if(pre=NULL) /a的前驱为空时 A-rheadi=a-rptr; /将a结点删除同时,在列地址A-cheadp-j中删除该结点若本行不是最后一行,则令a和b指向下一行行链表的首元素结点,转至(2);否则,算法结束。判断函数:int Judge_Cro

20、ssList(CrossList *A,CrossList *B)if(A-m=B-m&A-n=B-n) return 0; /符合返回0 else return 1; /不符合返回1该函数是用于判断矩阵A和矩阵B是否符合相加条件,即A和B的行数和列数是否相等,相等返回0,不相等返回1四、上机调试1、语法错误及修改:出现的语法问题是要在于子函数和变量定义,括号的配对,关键字和函数名称的书写,以及一些库函数的规范使用。这些问题均可以根据编译器的警告提示,对应的将其解决。2、逻辑问题修改和调整:判断矩阵A和B的相加问题:由于判断两矩阵是否符合相加条件,就是矩阵A和B的行数和列数是否相等,相等就执行

21、加法运算,若不相等就需要修正矩阵A或者B,就需要重新创建,而在程序中没有加入if(r=A) /修改矩阵A printf(n%c 矩阵A.n,1); A=Creat_CrossList(); Insert_CrossList(A); if(r=B) /修改矩阵B printf(n%c 矩阵B.n,1); B=Creat_CrossList(); Insert_CrossList(B);加入后就可以随时修改其中一个矩阵了,使其符合相加条件。在矩阵加法中,由于该程序是书上的,所以可以用现成的,但是在程序中有个问题,就是当a-v=a-v+b-v时,只有当相加结果为零的情况if(a-v=0) /若相加后

22、为值为0 if(pre=NULL) /a的前驱为空时 A-rheadi=a-rptr; /将a结点删除 else pre-rptr=a-rptr; /将a的前驱后移一位 p=a; /p指向被删除的结点 a=a-rptr; /a后移一位 if(A-cheadp-j=p) /p指向的结点为所在列的首元素时 A-cheadp-j=p-cptr;/将p从列链表中删除 acolp-j=p-cptr; else /找到p所在列链表的前驱结点 while(acolp-j-cptr!=p) acolp-j=acolp-j-cptr; acolp-j-cptr=p-cptr; /将p从列链表中删除 free(p

23、); /释放p指向结点的空间而没有相加不等于零的情况,即a-v!=0,因此需要加入如下函数 else /若相加后为值不为0 pre=a; /pre指向a a=a-rptr; /a后移一位 五、测试结果及其分析 1、系统运行登陆界面如图1-4所示:图1-42、系统的功能选项界面,如图1-5所示:图1-53、创建矩阵A并输入矩阵A,如图1-6所示:图1-64、创建矩阵B,并输入B,如图1-7所示:图1-75、矩阵A+B,由上面矩阵A和B的截图可知,A与B不符合相加条件,产生错误提示并修正。如图1-8所示:图1-8修改之后输出矩阵A+B的结果,如图1-9所示:图1-96、退出程序,如图1-10所示:

24、图1-10六、用户使用说明本程序执行文件为:矩阵的加法运算问题.exe进入本系统之后,会显示登陆界面菜单,根据提示操作。接着是进入欢迎登陆并使用矩阵加法计算器,然后按任意键继续,输入密码和账号,登陆即可以使用计算器了。然后根据计算器界面的提示选择您想要的功能操作。七、参考文献1 王昆仑,李红. 数据结构与算法. 北京:中国铁道出版社,2006年5月。2 严蔚敏 数据结构与算法 视频八、附录#include stdio.h#include malloc.h#define K 50 /预设稀疏矩阵的行数#define N 50 /预设稀疏矩阵的列数#include stdlib.h#include

25、 string.h/结点类型typedef struct nodeint i,j,v; /元素的行标、列标、值域 struct node *rptr,*cptr; /行指针域、列指针域OLNode; /十字链表类型typedef structOLNode *rheadK,*cheadN; /存放行链表及列链表的首地址 int m,n,t; /矩阵的行数、列数、非灵元素个数CrossList; /创建空十字链表CrossList *Creat_CrossList() CrossList *M; M=(CrossList *)malloc(sizeof(CrossList); printf(n%c 输入行数:,1); /输入行数 scanf(%d,&(M-m); while(M-mm); printf(n%c 输入列数:,1); /输入列数 scanf(%d,&(M-n); while(M-nn); printf(n%c 输入非零元素数个数:,1); /输入非零元素个数 scanf(%d,&(M-t); while(M-t0) printf(n%c 您输入的非零元

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

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