《数据结构》课程设计报告矩阵的运算.docx
- 文档编号:12702335
- 上传时间:2023-04-21
- 格式:DOCX
- 页数:23
- 大小:315.81KB
《数据结构》课程设计报告矩阵的运算.docx
《《数据结构》课程设计报告矩阵的运算.docx》由会员分享,可在线阅读,更多相关《《数据结构》课程设计报告矩阵的运算.docx(23页珍藏版)》请在冰豆网上搜索。
《数据结构》课程设计报告矩阵的运算
目录
1问题描述1
2需求分析1
3概要设计1
3.1抽象数据类型定义1
3.2模块划分2
4详细设计2
4.1数据类型的定义3
4.2主要模块的算法描述3
5测试分析9
6课程设计总结12
参考文献12
附录(源程序清单)13
1问题描述
用三元数组实现稀疏矩阵的加法,乘法,转置。
2需求分析
(1)先用do-while语句选择要操作的程序:
1、矩阵的相加,2、矩阵的相乘,3、矩阵转置。
(2)输入你想要操作的程序再用switch选择:
转置函数voidNormalTSMatrix(TSMatrixM,TSMatrix&T);
加法函数voidSeqAdd(TSMatrixa,TSMatrixb,TSMatrix&c);
乘法函数voidmultsmatrix(TSMatrixM,TSMatrixN,TSMatrix&T);
(3)在调用以上函数时先要建立三元数组输入函数voidInitTSM(TSMatrix*M)和矩阵的输出函数voidShowTSM(TSMatrixM)。
3概要设计
3.1抽象数据类型定义
ADTArray{
数据对象:
D={aj1j2…jn|n(>0)称为数组的维数,bi是数组第i维的长度,ji是数组元素的第i维下标,aj1j2…jn∈ElemSet,ji=0,…,bi-1,i=1,2,…,n}
数据关系:
R={R1,R2,…,Rn}
Ri={
aj1...ji...jn,aj1…ji+1…jn∈D,i=2,…,n}
基本操作:
InitArray(&A,n,bound1,…,boundn)
操作结果:
若维数n和各维长度合法,则构造相应的数组A,并返回OK。
DestroyArray(&A)
操作结果:
销毁数组A。
Value(A,&e,index1,…,indexn)
初始条件:
A是n维数组,e为元素变量,随后是n个下标值。
操作结果:
若各下标不越界,则e赋值为所指定的A的元素值,并返回OK。
Assign(&A,e,index1,…,indexn)
初始条件:
A是n维数组,e为元素变量,随后是n个下标值。
操作结果:
若下标不越界,则将e的值赋给所指定的A的元素,并返回OK。
}ADTArray
3.2模块划分
本程序包括三个模块:
(1)主程序模块
voidmain()
{
矩阵的相加
矩阵的相乘
矩阵的转置
}
(2)相加模块——实现矩阵的相加
(3)相乘模块——实现矩阵的相乘
(4)转置模块——实现矩阵的转置
4详细设计
4.1数据类型的定义
#defineMAXSIZE1000
typedefstruct{
inte;
inti,j;
}Triple;/*三元组类型定义*/
typedefstruct{
Tripledata[MAXSIZE+1];
intmu,nu,tu;
}TSMatrix;/*三元组顺序表类型定义*/
4.2主要模块的算法描述
(1)主函数
输入inti,进行switch选择:
当输入时1时操作1即进行矩阵的加法,同理输入时2和3时进行的是矩阵的乘法和转置;输入是其他数时不进行任何操作只输出的是“chooseerror”。
(2)建立三元数组矩阵
首先输入矩阵行数,列数,非零元素的个数,然后进行for循环,在循环中请输入元素所在行,列,值在判断m<=0||n<=0||m>M->mu||n>M->nu是否成立,若成立则输出inputerror!
,若不成立则执行M->data[i].i=m;M->data[i].j=n;M->data[i].e=e。
(3)输出矩阵(数学形式)
先是for语句控制输出的格式,再用两个for语句控制矩阵的行和列在等二个for语句中用if语句判断M.data[t].i==m&&M.data[t].j==n若成立则printf("%d\t",M.data[t].e);t++;否则printf("0\t"),即在矩阵中没有数的地方输出0。
(4)矩阵的加法
首先进行是while(i<=a.tu&&j<=b.tu)循环,在此循环中分别判断两矩阵的行相等和不相等,列的相等和不相等时要分别执行不同的语句即a的行号等于b的行号和a的列号等于b的列号时此时将他们的数据直接相加;a的行号等于b的行号和a的列号小于b的列号时相加后的值等于列号更小的矩阵中对应元素的值;如果a的列号大于b的列号且行号相等,则相加后的值等于列号更小的矩阵中对应元素的值;如果a的行号小于b的行号且列号相等,则相加后的值等于行号更小的矩阵中对应元素的值;如果a的行号大于b的行号且列号相等,则相加后的值等于行号更小的矩阵中对应元素的值。
然后执行while(i<=a.tu)和while(j<=b.tu)循环。
(5)矩阵的相乘
if(M.nu!
=N.mu)则两矩阵无法相乘,若能相乘则M的行等于相的行等于相的行等于相乘之后的行,N的列等于相乘之后的列。
设Qe为矩阵T的临时数组矩阵,Qe的第i行j列的元素值存于*(Qe+(M.data[i].i-1)*N.nu+N.data[j].j)中,初值为0,把结果累加到Qe中,Qe矩阵中,因为M的每一行和N的每一列相乘都是T的一个元素,不管它是零或非零当M的第一行和N的第一列相乘则得T的第一个元素;当M的第一行和N的第二列相乘则得T的第二个元素当M的第i行和N的第j列相乘则得T的第p个元素;根据归纳法得p=(i-1)*N的列数+j,且非零元个数加一。
其中Multiplex代表语句{Qn++;T->data[Qn].e=*(Qe+(i-1)*N.nu+j);T->data[Qn].i=i;T->data[Qn].j=j;}。
(6)矩阵的转置
先把矩阵M的行数和列数分别赋给转置后矩阵T的列数和行数,元素个数不变;然后再找出矩阵的M的i列元素,得到矩阵T的i行元素,直至全部转置完。
5测试分析
测试数据及结果如下
矩阵的加法测试分析结果如下:
根据矩阵加法测试结果分析可知:
矩阵的加法是要比较矩阵A的行和列与矩阵B行和列分别之间大小,来执行不同的语句。
矩阵乘法测试分析结果如下:
根据矩阵乘法测试结果分析可知:
首先要判断矩阵的列数是否与矩阵的行数相等,如果若相等则执行乘法相关语句,否则不能进行乘法语句。
矩阵转置测试分析结果如下:
根据矩阵转置测试结果分析:
只要你输入的矩阵是对的则就能转置。
但注意不要超过MAXSIZE的值。
6课程设计总结
通过这次课程设计使我充分的理解了用三元数组实现稀疏矩阵的加法,乘法,转置。
。
虽然此次的程序不是很完备,但是总体还是一个比较能体现数据结构知识点能力的程序了,当然只是相对于我这个初学者来说。
在刚开始编程的时候,我感到很吃力,不知如何去编写源程序,后来柳老师叫我们去看此题目要用到那些知识和去上网搜索相关程序,此后经过一个星期的努力终于编好了源程序,可是不能运行,我们这小组经过反复的讨论都没找出错误,此时我们只好请教柳老师,老师一看就发现了问题原来我们定义的MAXSIZE的值溢出了。
其余的问题不大,只是程序不够完美。
所以我们又对程序进行改进直至完成。
在此我非常要感谢的是我的指导老师柳小文老师,感谢老师的细心认真的辅导,让我对数据结构这门课程有了一定的研究。
参考文献
[1]黄同成,黄俊民,董建寅.数据结构[M].北京:
中国电力出版社,2008
[2]董建寅,黄俊民,黄同成.数据结构实验指导与题解[M].北京:
中国电力出版社,2008
[3]严蔚敏,吴伟民.数据结构(C语言版)[M].北京:
清华大学出版社,2002
[4]刘振鹏,张晓莉,郝杰.数据结构[M].北京:
中国铁道出版社,2003
[5]张福祥,C语言程序设计.沈阳:
辽宁大学出版社,2008
附录(源程序清单)
#include"stdio.h"
#include"stdlib.h"
#include"malloc.h"
#defineMAXSIZE1000
typedefstruct{
inte;
inti,j;
}Triple;/*三元组类型定义*/
typedefstruct{
Tripledata[MAXSIZE+1];
intmu,nu,tu;
}TSMatrix;/*三元组顺序表类型定义*/
voidInitTSM(TSMatrix*M);//函数声明
voidShowTSM(TSMatrixM);
voidNormalTSMatrix(TSMatrixM,TSMatrix*T);
voidSeqAdd(TSMatrixa,TSMatrixb,TSMatrix*c);
voidmultsmatrix(TSMatrixM,TSMatrixN,TSMatrix*T);
voidmain()//主函数
{
inti;
TSMatrixsm,sm1,sm2,sm3,tsm;
do{
printf("**********************************\n");
printf("请选择你想要的操作\n");
printf("");
printf("1矩阵相加");
printf("2矩阵相乘");
printf("3转置\n");
scanf("%d",&i);
switch(i)
{
case1:
system("cls");
printf("请创建A矩阵\n");
InitTSM(&sm1);
ShowTSM(sm1);
printf("请创建B矩阵\n");
InitTSM(&sm2);
ShowTSM(sm2);
printf("A加上B为:
\n");
SeqAdd(sm1,sm2,&sm3);
printf("************************************\n");
ShowTSM(sm3);
break;
case2:
system("cls");
printf("请创建A矩阵\n");
InitTSM(&sm1);
ShowTSM(sm1);
printf("请创建B矩阵\n");
InitTSM(&sm2);
ShowTSM(sm2);
printf("A乘以B为:
\n");
multsmatrix(sm1,sm2,&sm3);
ShowTSM(sm3);
break;
case3:
system("cls");
printf("请创建矩阵\n");
InitTSM(&sm);
ShowTSM(sm);
printf("矩阵转置为:
\n");
NormalTSMatrix(sm,&tsm);
ShowTSM(tsm);
break;
default:
printf("chooseerror!
\n");
}
}while(i!
=0);
}
voidInitTSM(TSMatrix*M)//初始化数组元素
{
inte,m,n,t,i;
printf("请输入矩阵行数,列数,非零元素的个数:
\n");
scanf("%d%d%d",&m,&n,&t);
M->mu=m;
M->nu=n;
M->tu=t;
for(i=1;i<=t;i++)
{
printf("请输入元素所在行,列,值:
");
scanf("%d%d%d",&m,&n,&e);
if(m<=0||n<=0||m>M->mu||n>M->nu)
{
printf("inputerror!
\n");
i--;
}
else
{
M->data[i].i=m;
M->data[i].j=n;
M->data[i].e=e;
}
}
}
voidShowTSM(TSMatrixM)//显示数组元素
{
intm,n,i,t=1;
printf("则矩阵为:
\n");
for(i=1;i<=M.nu;i++)
printf("%d\t",i);
printf("\n");
printf("*********************************************************\n");
for(m=1;m<=M.mu;m++)
{
for(n=1;n<=M.nu;n++)
{
if(M.data[t].i==m&&M.data[t].j==n)
{
printf("%d\t",M.data[t].e);
t++;
}
else
printf("0\t");
}
printf("\n");
}
}
voidNormalTSMatrix(TSMatrixM,TSMatrix*T)//矩阵转置
{
T->mu=M.nu;
T->nu=M.mu;
T->tu=M.tu;
if(T->tu)
{
intt,i,k=1;
for(i=1;i for(t=1;t<=M.tu;t++) { if(M.data[t].j==i) { T->data[k].i=M.data[t].j; T->data[k].j=M.data[t].i; T->data[k++].e=M.data[t].e; } } } } voidSeqAdd(TSMatrixa,TSMatrixb,TSMatrix*c)//矩阵加法 { inti=1,j=1,k=1;//下标置初始值 while(i<=a.tu&&j<=b.tu) { if(a.data[i].i==b.data[j].i)//a的行号等于b的行号 { if(a.data[i].j==b.data[j].j)//a的列号等于b的列号 { c->data[k].i=a.data[i].i; c->data[k].j=a.data[i].j; c->data[k].e=a.data[i].e+b.data[j].e;//此时将他们的数据直接相加 i++; j++; k++; } elseif(a.data[i].j { c->data[k].i=a.data[i].i; c->data[k].j=a.data[i].j; c->data[k].e=a.data[i].e;//如果行号相等,则相加后的值等于列号更小的矩阵中对应元素的值 i++; k++; } elseif(a.data[i].j>b.data[j].j)//a的列号大于b的列号 { c->data[k].i=b.data[j].i; c->data[k].j=b.data[j].j; c->data[k].e=b.data[j].e;//如果行号相等,则相加后的值等于列号更小的矩阵中对应元素的值 j++; k++; } } elseif(a.data[i].i { c->data[k].i=a.data[i].i; c->data[k].j=a.data[i].j; c->data[k].e=a.data[i].e;//如果列号相等,则相加后的值等于行号更小的矩阵中对应元素的值 i++; k++; } elseif(a.data[i].i>b.data[j].i)//a的行号大于b的行号 { c->data[k].i=b.data[j].i; c->data[k].j=b.data[j].j; c->data[k].e=b.data[j].e;//如果列号相等,则相加后的值等于行号更小的矩阵中对应元素的值 j++; k++; } } while(i<=a.tu) { c->data[k].e=a.data[i].e; c->data[k].i=a.data[i].i; c->data[k].j=a.data[i].j; i++; k++; } while(j<=b.tu) { c->data[k].e=a.data[j].e; c->data[k].i=a.data[j].i; c->data[k].j=a.data[j].j; j++; k++; } c->nu=a.nu; c->mu=a.mu; c->tu=k; } voidmultsmatrix(TSMatrixM,TSMatrixN,TSMatrix*T)//矩阵乘法 { inti,j,Qn=0; int*Qe; if(M.nu! =N.mu) {printf("两矩阵无法相乘");} T->mu=M.mu; T->nu=N.nu; Qe=(int*)malloc(M.mu*N.nu*sizeof(int));/*Qe为矩阵Q的临时数组*/ for(i=1;i<=M.mu*N.nu;i++) *(Qe+i)=0;/*矩阵Q的第i行j列的元素值存于*(Qe+(M.data[i].i-1)*N.nu+N.data[j].j)中,初值为0*/ for(i=1;i<=M.tu;i++)/*结果累加到Qe*/ for(j=1;j<=N.tu;j++) if(M.data[i].j==N.data[j].i) *(Qe+(M.data[i].i-1)*N.nu+N.data[j].j)+=M.data[i].e*N.data[j].e; for(i=1;i<=M.mu;i++)/*Qe矩阵中,因为M的每一行和N的每一列相乘都是T的一个元素,不管它是零或非零*/ for(j=1;j<=N.nu;j++)/*当M的第一行和N的第一列相乘则得T的第一个元素;当M的第一行和N的第二列相乘则得T的第二个元素;*/ if(*(Qe+(i-1)*N.nu+j)! =0)/*当M的第i行和N的第j列相乘则得T的第p个元素;根据归纳法得p=(i-1)*N的列数+j*/ { Qn++;//非零元个数加一 T->data[Qn].e=*(Qe+(i-1)*N.nu+j); T->data[Qn].i=i; T->data[Qn].j=j; } T->tu=Qn; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 报告 矩阵 运算