《数据结构》实验
班级:10020801姓 名:吴亮 学 号:2008302651 电 话 151********日期:2009.11.26
◎实验题目: 进行矩阵的转置运算,加法运算和乘法运算
◎实验目的:1.熟悉矩阵的定义与以三元组形式输入
2.学会矩阵的转置运算,加法运算和乘法运算(以行逻辑连接形式)
3.掌握用矩阵形式输出
◎实验内容:设计一个程序,1、演示矩阵的转置运算与加法运算。2、(扩展)以行逻辑连接形式进行乘法运算
一、需求分析
1、本实验中的输入为三个以三元组形式输入的矩阵
2、本实验以矩阵的形式输出计算结果
3、程序能够完成对输入的矩阵执行转置于加法运算后输出结果;将输入的矩阵进行乘法,然后输出结果。
4、测试数据:
选择0
再输入 3 3 2
输入矩阵:2 2 1
2 3 2
出现:转置后矩阵
0 0 0
0 1 0
0 2 0
选择1
再输入 3 3 2
输入矩阵:2 2 1
2 3 2
再输入 3 3 2
输入矩阵:2 2 1
3 2 2
出现相加后矩阵
0 0 0
0 2 2
0 2 0
选择2
再输入 3 3 2
输入矩阵:2 2 1
2 3 2
再输入 3 3 2
输入矩阵:2 2 1
3 2 2
出现运算后矩阵
0 0 0
0 5 0
0 0 0
二 概要设计
程序中采用了三元组作为存储结构
1、基本操作如下:
(1)table * scanff() 操作结果:建立矩阵
(2)table * transpose(table *a) 初始条件:矩阵已存在;操作结果:将矩阵转置
(3)void tableplus(table *a,table *b) 初始条件:矩阵已存在;
操作结果:将a,b矩阵相加
(4)table * tablemult(table *a,table *b) 初始条件:矩阵已存在
操作结果:将a,b矩阵相乘
(5)void Rpos(table *a) 初始条件:矩阵已存在 操作结果:将a中的每行第一个非零元
下来
2、本程序包含七个模块:主程序模块;建立矩阵的模块;转置运算的模块;加法运算的模块;乘法运算的模块;记录每行非零元的模块,输出矩阵的模块
三 详细设计
1、矩阵的定义:typedef struct{
int r;
int c;
ElemType e;
}tupletype;
typedef struct{
int rows;
int cols;
int nums;
tupletype data[NUM+1];
int rpos[ROW+1];
}table;
2、每个模块的分析:
(1)主程序模块:
void main()
{
table *A,*B,*C;
int i;
printf("请选择你的操作:0,转置;1,加法;2,乘法;\n");
scanf("%d",&i);
printf("请输入第一个矩阵行数、列数及非零数的个数:\n");
A=scanff();
if(i==0)
{
C=transpose(A);//进行转置
print(C);
}
else if(i==1)
{
printf("请输入第二个矩阵行数、列数及非零数的个数:\n");
B=scanff();
tableplus(A,B);
}
else
{
printf("请输入第二个矩阵行数、列数及非零数的个数:\n");
B=scanff();
C=tablemult(A,B);
print(C);
}
}
(2)建立矩阵的模块
table * scanff()
{//建立矩阵
table * a;
int k;
a=(table * )malloc(sizeof(table));
scanf("%d%d%d",&(a->rows),&(a->cols),&(a->nums));
printf("建立三元组:\n");
for(k=1;k<=a->nums;k++)
scanf("%d%d%d",&(a->data[k].r),&(a->data[k].c),&(a->data[k].e));
return a;
}
(3)转置运算的模块
table * transpose(table *a)
{
table *b;
int brow,acol,k;
b=(table * )malloc(sizeof(table));
b->rows=a->cols;
b->cols=a->cols;
b->nums=a->nums;
if(b->nums>0){
brow=1;
for(acol=1;acol<=a->cols;acol++)
for(k=1;k<=a->nums;k++)
if(a->data[k].c==acol)
{
b->data[brow].c=a->data[k].r;
b->data[brow].r=a->data[k].c;
b->data[brow].e=a->data[k].e;
brow++;
}
}
return b;
}
(4)加法运算的模块
void tableplus(table *a,table *b)
{
table *c;
int m,n,k,l,h;
c=(table * )malloc(sizeof(table));
if(b->rows!=a->rows||b->cols!=a->cols) printf("ERROR");
else
{
c->rows=a->rows;
c->cols=a->cols;
c->nums=1;
for(h=1;h<=b->nums;)
{ for(m=1;m<=c->rows;m++)
for(n=1;n<=c->cols;n++)
if(b->data[h].r==m&&b->data[h].c==n)
{
c->data[(c->cols)*(m-1)+n].r=m;
c->data[(c->cols)*(m-1)+n].c=n;
c->data[(c->cols)*(m-1)+n].e=b->data[h].e;
h++;
}
}
for(h=1;h<=b->nums;h++)
{ for(l=1;l<=a->nums;l++)
if((a->data[l].r==b->data[h].r)&&(a->data[l].c==b->data[h].c))
a->data[l].e=a->data[l].e+b->data[h].e;
}
for(k=1;k<=a->nums;)
{ for(m=1;m<=c->rows;m++)
for(n=1;n<=c->cols;n++)
if(a->data[k].r==m&&a->data[k].c==n)
{
c->data[(c->cols)*(m-1)+n].r=m;
c->data[(c->cols)*(m-1)+n].c=n;
c->data[(c->cols)*(m-1)+n].e=a->data[k].e;
k++;
}
}
}
printf("输出矩阵:\n");
for(m=1;m<=c->rows;m++)
{
for(n=1;n<=c->cols;n++)
if((c->data[(c->cols)*(m-1)+n].r!=m)||(c->data[(c->cols)*(m-1)+n].c!=n))
printf("0 ");
else printf("%d ",c->data[(c->cols)*(m-1)+n].e);
printf("\n");
}
}
(5)乘法运算的模块
table * tablemult(table *a,table *b)
{
table *c;
int k,tp,t,p,q;
int ctemp[10];
int arow,brow,ccol;
c=(table * )malloc(sizeof(table));
if(a->cols!=b->rows) printf("ERROR");
else {
c->rows=a->rows;
c->cols=b->cols;
c->nums=0;
Rpos(a);
Rpos(b);
if(a->nums*b->nums!=0){
for(arow=1;arow<=a->rows;arow++)
{
for(k=1;k<=a->cols;k++)
ctemp[k]=0;
c->rpos[arow]=c->nums+1;
if(arow
rows)
tp=a->rpos[arow+1];
else
tp=a->nums+1;
for(p=a->rpos[arow];pdata[p].c;
if(browrows)
t=b->rpos[brow+1];
else
t=b->nums+1;
for(q=b->rpos[brow];qdata[q].c;
ctemp[ccol]+=a->data[p].e*b->data[q].e;
}
}
for(ccol=1;ccol<=c->cols;++ccol)
if(ctemp[ccol])
{
if(++c->nums>NUM)
printf("ERROR");
c->data[c->nums].r=arow;
c->data[c->nums].c=ccol;
c->data[c->nums].e=ctemp[ccol];
}
}
}
}
return c;
}
(6)记录每行非零元的模块
void Rpos(table *a)
{
int t,row;
int num[10];
for(row=1;row<=a->rows;++row) num[row]=0;
for(t=1;t<=a->nums;++t) ++num[a->data[t].r];
a->rpos[1]=1;
for(row=2;row<=a->rows;++row)
a->rpos[row]=a->rpos[row-1]+num[row-1];
}
(7)输出矩阵的模块
void print(table *a)
{//输出函数
int k,l,m;
printf("输出矩阵:\n");
m=1;
for(k=1;k<=a->rows;k++)
{ for(l=1;l<=a->cols;l++)
{
if(m>a->nums) printf("0 ");
else if(a->data[m].c==l&&a->data[m].r==k)
{
printf("%d ",a->data[m].e);++m;
}
else printf("0 ");
}
printf("\n");//换行
}
}四 使用说明、测试分析及结果
1.程序使用说明
(1)本程序的运行环境为VC6.0。
(2)进入演示程序后即显示提示如下信息:
请选择你的操作:0,转置;1,加法;2,乘法
选择后出现:请输入矩阵行数、列数及非零数的个数
建立三元组:按三元组形式输入矩阵
(3)测试结果:
选择0
再输入 3 3 2
输入矩阵:2 2 1
2 3 2
出现:转置后矩阵
0 0 0
0 1 0
0 2 0
选择1
再输入 3 3 2
输入矩阵:2 2 1
2 3 2
再输入 3 3 2
输入矩阵:2 2 1
3 2 2
出现相加后矩阵
0 0 0
0 2 2
0 2 0
选择2
再输入 3 3 2
输入矩阵:2 2 1
2 3 2
再输入 3 3 2
输入矩阵:2 2 1
3 2 2
出现运算后矩阵
0 0 0
0 5 0
0 0 0
五、实验(实验)
1、你在编程过程中花时多少?
10小时
2、多少时间在纸上设计?
2.5小时
3、多少时间上机输入和调试?
5小时
4、多少时间在思考问题?
2.5小时
5、遇到了哪些难题?你是怎么克服的?
答:加法算法花费了我好多时间,开始想的第一个算法在单个调试时没问题,但放入整个程序中却运算不出正确结果。后来参考了同学的算法才做出程序!
6、你的收获有哪些?
答:在程序设计中要多思考,多在纸上设计,多与同学老师交流,才能更好更快的完成程序。并且这一次自己终于学会了完整的调试程序,这让自己很是高兴,期盼下一次编程快些到来。
教师评语:
实验成绩:
指导教师签名:
批阅日期: