数据结构实验.docx
《数据结构实验.docx》由会员分享,可在线阅读,更多相关《数据结构实验.docx(16页珍藏版)》请在冰豆网上搜索。
![数据结构实验.docx](https://file1.bdocx.com/fileroot1/2023-1/22/c66d888c-c961-40be-905c-e906478d66bd/c66d888c-c961-40be-905c-e906478d66bd1.gif)
数据结构实验
滨江学院
数据结构课程设计
题目稀疏矩阵运算器
院系理学系
年级班级2012级信息与计算科学
学生姓名顾杨
学号20122314007
学期2014-2015
(一)
任课教师黄群
二O一四年十二月十日
1引言
本次课程设计的目的是深入研究数组的存储表示和实现技术,熟悉广义表存储结构的特性。
2需求分析
1.本演示程序中,矩阵的行列人为规定,由个人输入需要计算的矩阵,首先选择自己需要计算方式,在输入所需要计算的矩阵,程序将根据选择进行计算,最后输出结果。
2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入相应数据(所需计算矩阵的行列数及矩阵内个元素),程序将自动将稀疏矩阵保存在三元标中。
3.程序执行的命令包括:
(1)构建三元列表;
(2)输入所需计算矩阵的行列数;(3)输入矩阵内的全部元素(4)根据选择进行矩阵计算(5)输出矩阵
4.测试数据
(1)a.mu=3a.nu=3,101
200
021
b.mub.nu012
111
102
加法输出:
113减法输出:
1-1-1乘法输出:
114
3111-1-1000
123-12-1302
3概要设计
为了实现上述操作,应以单向循环链表为存储结构。
1.input(&b)
基本操作:
以此输入稀疏矩阵内每个元素
操作结果:
建立三元列表b,并想稀疏矩阵内输入数据
addmtirx(&a,&b,&c);
初始条件:
存在两个不为空稀疏矩阵和一个空的三元列表
操作结果:
将两个稀疏矩阵相加,并将得数存储在c中
transposesmatrix(&a,&b);
初始条件:
存在一个不为空稀疏矩阵和一个空的三元列表
操作结果:
将含有数据的稀疏矩阵转置,并将得数存储在b中
multmatrix(&a,&b,&c);
初始条件:
存在两个不为空稀疏矩阵和一个空的三元列表
操作结果:
将两个稀疏矩阵相乘,并将得数存储在c中
submtirx(&a,&b,&c)
初始条件:
存在两个不为空稀疏矩阵和一个空的三元列表
操作结果:
将两个稀疏矩阵相加减,并将得数存储在c中
Output()
初始条件:
存放稀疏矩阵三元列表存在
操作结果:
输出计算后的稀疏矩阵
2.本程序包含三个模块:
(1)主程序模块;
(2)输入需要计算的稀疏矩阵
(3)选择计算方法,并计算
(4)输出计算后的矩阵
(5)模块调用图:
主程序模块
输入需要计算的稀疏矩阵
选择计算方法,并计算
输出计算后的矩阵
4详细设计
1.元素类型,列表类型和指针类型:
#include
#include
#definemaxsize100
typedefintdatatype;
typedefstruct//定义三元组
{
inti,j;
datatypex;
}matrix;
typedefstruct//定义三元组表
{
matrixdata[maxsize];
intmu,nu,tu;//矩阵行,列,非零元个数
}tripulematrix;
2.每个模块的分析:
(1)主程序模块:
voidmain()
{
printf("----------------矩阵计算---------------\n");
printf("请选择你需要的计算方式\n");
printf("-----------------1.稀疏矩阵的转置---------------\n");
printf("-----------------2.稀疏矩阵的加法---------------\n");
printf("-----------------3.稀疏矩阵的减法---------------\n");
printf("-----------------4.稀疏矩阵的乘法---------------\n");
printf("-----------------5.退出---------------\n");
charx;
scanf("%c",&x);
tripulematrixa,b,c;
switch(x)
{
case'1':
//tripulematrixa,b;
printf("请输入矩阵的行数与列数\n");
scanf("%d%d",&a.mu,&a.nu);
b.mu=a.mu;
b.nu=a.nu;
printf("请输入一个矩阵,例如:
\n");
printf("123\n234\n456\n");
printf("请输入\n");
input(&a);
transposesmatrix(&a,&b);
output(&b);
break;
case'2':
//tripulematrixa,b,c;
printf("请输入矩阵的行数与列数\n");
scanf("%d%d",&a.mu,&a.nu);
b.mu=a.mu;
b.nu=a.nu;
printf("请输入两个矩阵,例如:
\n");
printf("123\n234\n456\n");
printf("请输入\n");
printf("请输入第一个矩阵\n");
input(&a);
printf("请输入第二个矩阵\n");
input(&b);
addmtirx(&a,&b,&c);
output(&c);
break;
case'3':
//tripulematrixa,b,c;;
printf("请输入矩阵的行数与列数\n");
scanf("%d%d",&a.mu,&a.nu);
b.mu=a.mu;
b.nu=a.nu;
printf("请输入两个矩阵,例如:
\n");
printf("123\n234\n456\n");
printf("请输入\n");
printf("请输入第一个矩阵\n");
input(&a);
printf("请输入第二个矩阵\n");
input(&b);
submtirx(&a,&b,&c);
break;
case'4':
//tripulematrixa,b,c;;
printf("请输入矩阵的行数与列数\n");
scanf("%d%d",&a.mu,&a.nu);
b.mu=a.mu;
b.nu=a.nu;
printf("请输入两个矩阵,例如:
\n");
printf("123\n234\n456\n");
printf("请输入第一个矩阵\n");
input(&a);
printf("请输入第二个矩阵\n");
input(&b);
multmatrix(&a,&b,&c);
break;
case'5':
exit(0);
break;
system("pause");
}
(2)输入数据
voidinput(tripulematrix*a)
{
inti,j,k=0;
datatypex;
for(i=0;imu;i++)
{
for(j=0;jnu;j++)
{
scanf("%d",&x);
if(x)//如果是非零元
{
a->data[k].i=i;
a->data[k].j=j;
a->data[k].x=x;
k++;
}
}
}
a->tu=k;
}//input
(3)加法
datatypeaddmtirx(tripulematrix*a,tripulematrix*b,tripulematrix*c)
{
intk=0,l=0;
c->mu=a->mu;
c->nu=a->nu;
c->tu=0;
while(ktu&<u)
{
if((a->data[k].i==b->data[l].i)&&(a->data[k].j==b->data[l].j))
{
inttemp=a->data[k].x+b->data[l].x;
if(temp!
=0)
{
c->data[c->tu].x=a->data[k].x+b->data[l].x;
c->data[c->tu].i=a->data[k].i;
c->data[c->tu].j=a->data[k].j;
c->tu++;
}
k++;l++;
}
else
if((a->data[k].i==b->data[l].i)&&(a->data[k].jdata[l].j))
{
c->data[c->tu].x=a->data[k].x;
c->data[c->tu].i=a->data[k].i;
c->data[c->tu].j=a->data[k].j;
c->tu++;
k++;
}
else
{
if(((a->data[k].i==b->data[l].i)&&(a->data[k].j>b->data[l].j))||(a->data[k].i>b->data[l].i))
{
c->data[c->tu].i=b->data[l].i;
c->data[c->tu].j=b->data[l].j;
c->data[c->tu].x=b->data[l].x;
c->tu++;
l++;
}
}
}
while(ktu)
{
c->data[c->tu].x=a->data[k].x;
c->data[c->tu].i=a->data[k].i;
c->data[c->tu].j=a->data[k].j;
c->tu++;
k++;
}
while(ltu)
{
c->data[c->tu].i=b->data[l].i;
c->data[c->tu].j=b->data[l].j;
c->data[c->tu].x=b->data[l].x;
c->tu++;
l++;
}
return
(1);
}
(4)减法
datatypesubmtirx(tripulematrix*a,tripulematrix*b,tripulematrix*c)//减法
{
intk=0,l=0;
c->mu=a->mu;
c->nu=a->nu;
c->tu=0;
while(ktu&<u)
{
if((a->data[k].i==b->data[l].i)&&(a->data[k].j==b->data[l].j))
{
//inttemp=a->data[k].x-b->data[l].x;
//if(temp!
=0)
//{
c->data[c->tu].x=a->data[k].x-b->data[l].x;
c->data[c->tu].i=a->data[k].i;
c->data[c->tu].j=a->data[k].j;
c->tu++;
//}
k++;l++;
}
else
if((a->data[k].i==b->data[l].i)&&(a->data[k].jdata[l].j)||(a->data[k].idata[l].i))
{
c->data[c->tu].x=a->data[k].x;
c->data[c->tu].i=a->data[k].i;
c->data[c->tu].j=a->data[k].j;
c->tu++;
k++;
}
else
{
if(((a->data[k].i==b->data[l].i)&&(a->data[k].j>b->data[l].j))||(a->data[k].i>b->data[l].i))
{
c->data[c->tu].i=b->data[l].i;
c->data[c->tu].j=b->data[l].j;
c->data[c->tu].x=-b->data[l].x;
c->tu++;
l++;
}
}
}
while(ktu)
{
c->data[c->tu].x=a->data[k].x;
c->data[c->tu].i=a->data[k].i;
c->data[c->tu].j=a->data[k].j;
c->tu++;
k++;
}
while(ltu)
{
c->data[c->tu].i=b->data[l].i;
c->data[c->tu].j=b->data[l].j;
c->data[c->tu].x=-b->data[l].x;
c->tu++;
l++;
}
return
(1);
}
(5)转置
inttransposemartix(tripulematrix*a,tripulematrix*b)
{
intcol,p,q;
b->mu=a->nu;
b->nu=a->mu;
b->tu=a->tu;
if(b->tu)
{
q=0;
for(col=0;colnu;col++)
{
for(p=0;ptu;p++)
if(a->data[p].j==col)
{
b->data[p].i=a->data[q].j;
b->data[p].j=a->data[q].i;
b->data[p].x=a->data[q].x;
q++;
}
}
}
return
(1);
}//稀疏矩阵的转置算法
(六)乘法intmultmatrix(tripulematrix*a,tripulematrix*b,tripulematrix*c)
{
intrpos1[maxsize],rpos2[maxsize],num[maxsize],rpos3[maxsize];
introw1,row2,arow,tp,t,brow,ccol,p,q,k;
intctemp[maxsize];
if(a->tu)
{
for(row1=0;row1mu;row1++)
{
num[row1]=0;
}
for(row1=0;row1tu;row1++)
{
++num[a->data[row1].i];
}
rpos1[0]=0;
for(row1=1;row1mu;row1++)
{
rpos1[row1]=rpos1[row1-1]+num[row1-1];
}
}
if(b->tu)
{
for(row2=0;row2tu;row2++)
{
num[row2]=0;
}
for(row2=0;row2tu;row2++)++num[b->data[row2].i];
rpos2[0]=0;
for(row2=1;row2mu;row2++)rpos2[row2]=rpos2[row2-1]+num[row2-1];
}
c->mu=a->mu;c->nu=b->nu;c->tu=0;
if(a->tu*b->tu!
=0)
{
for(arow=0;arowmu;arow++)
{
for(k=0;krpos3[arow]=c->tu+1;
if(arowmu-1)
{
tp=rpos1[arow+1];
}
else
tp=a->tu;
for(p=rpos1[arow];p{
brow=a->data[p].j;//找到对应元在b中的行号
if(brownu-1)
{
t=rpos2[brow+1];
}
elset=b->tu;
for(q=rpos2[brow];q{
ccol=b->data[q].j;//乘积元素在Q中的列号
ctemp[ccol]+=(a->data[p].x)*(b->data[q].x);
}
}
for(ccol=0;ccolnu;ccol++)
{
if(ctemp[ccol])
{
if(c->tu>maxsize)
{
return0;
}
c->data[c->tu].i=arow;
c->data[c->tu].j=ccol;
c->data[c->tu].x=ctemp[ccol];
c->tu++;
}
}
}
}
return1;
}
(4)函数调用关系图
main()
input(&a);
transposesmatrix(&a,&b);
submtirx(&a,&b,&c);
addmtirx(&a,&b,&c);
multmatrix(&a,&b,&c);
output();
5程序使用说明及测试结果
1.程序使用说明
(1)本程序的运行环境为VC6.0。
(2)进入演示程序后即显示提示信息:
----------------矩阵计算---------------
请选择你需要的计算方式
-----------------1.稀疏矩阵的转置---------------
-----------------2.稀疏矩阵的加法---------------
-----------------3.稀疏矩阵的减法---------------
-----------------4.稀疏矩阵的乘法---------------
-----------------5.退出---------------
1
请输入矩阵的行数与列数
33
请输入一个矩阵,例如:
123
111
111
得出:
111
211
311
请按任意键继续...
3.调试中的错误及解决办法。
(1)转置出现问题
(2)输出时无法利用数组第一个空间
(3)三元表定义是无rpos(每行第一个非零元位置)
解决方式:
逐步调试,以及问同学,自己更改算法,计算出rpos
6致谢
经过1个月的忙碌和努力,此次论文设计也将基本完成。
作为一个本科生的论文,由于我自身经验的匮乏及学识所限,不可避免仍有许多疏忽错漏的细节。
如果没有导师的督促指点,以及一起研究的同学们的支持和鼓励,完成这次毕业设计就将是愚公移山,断不可行。
在此次论文写作过程中,老师对我的亲切关怀和耐心指导尤其激励着我。
她恭肃的学术态度,严谨的治学精神,认真专注的工作作风,给我留下深刻的印象并成为我今后学习生活的目标。
从最初的选择课题到最终完成论文,老师都始终非常耐心的指导和帮助我。
衷心感谢各位老师在百忙中评阅本论文,并提出了宝贵意见。
本文引用了数位学者的研究文献,正是各位学者的研究成果才启发我完成了本篇论文的写作。
由于我的个人水平局限,这篇论文难免有不足之处,恳请各位老师批评指正!