《数据结构课程设计》实验报告
一、实验目的:
理解稀疏矩阵的加法运算,掌握稀疏矩阵的存储方法,即顺序存储的方式,利用顺序存储的特点——每一个元素都有一个直接前驱和一个直接后继,完成相关的操作。
二、内容与设计思想:
1、设计思想
1)主界面的设计
定义两个矩阵a= 0 0 3 0 0 0 0 0 b= 0 2 0 0 0 0 0 0
0 0 0 0 0 0 5 0 0 0 0 4 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 6 0 0
0 0 0 0 7 0 0 0 0 0 0 0 8 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0
定义两个数组A和B,用于存储矩阵a和矩阵b的值;定义一个数组C,用于存放数组A 和数组B相加后的结果。
2)实现方式
稀疏矩阵的存储比较浪费空间,所以我们可以定义两个数组A、B,采用压缩存储的方式来对上面的两个矩阵进行存储。
具体的方法是,将非零元素的值和它所在的行号、列号作为一个结点存放在一起,这就唯一确定一个非零元素的三元组(i、j、v)。
将表示稀疏矩阵的非零元素的三元组按行优先的顺序排列,则得到一个其结点均为三元组的线性表。
即:以一维数组顺序存放非零元素的行号、列号和数值,行号-1作为结束标志。
例如,上面的矩阵a,利用数组A存储后内容为:
A[0]=0,A[1]=2, A[2]=3, A[3]=1, A[4]=6, A[5]=5, A[6]=3, A[7]=4, A[8]=7, A[9]=5, A[10]=1, A[11]=9, A[12]=-1
同理,用数组B存储矩阵b的值。
2、主要数据结构
稀疏矩阵的转存算法:
void CreateMatrix(int A[m][n],int B[50])
{
int i,j,k=0;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
if(A[i][j]!=0){
B[k]=i;k++;
B[k]=j;k++;
B[k]=A[i][j];k++;
}
B[k]=-1;
}
稀疏矩阵的加法实现:
3、主要算法结构分析:
1)void CreateMatrix(int A[m][n],int B[50]),这是一个将稀疏矩阵转存的函数,类似于顺序存储三元组表。
在这个方法中,只要用一个二重循环来判断每个矩阵元素是否为零,若不为零,则将其行、列下标及其值存入到一维数组B中对应的元素。
在定义函数的过程中,我们需要定义一个for循环,以完成行和列的转换及存储。
在函数的末尾我们定义一个B[K]=-1,用于结束非零元素的存储。
2)void MatrixAdd(int A[max],int B[max],int C[max]),这个函数用于实现数组A和数组B的相加,并将其相加的结果存入数组C。
这个函数讨论了数组在相加的过程中的几种情况:
a、A数组和B数组的行相等且列相等,两者直接相加后存入数组C中。
if(A[i]==B[j])
{
if(A[i+1]==B[j+1])
{
C[k]=A[i];
C[k+1]=A[i+1];
C[k+2]=A[i+2]+B[j+2];
k=k+3;
i=i+3;
j=j+3;
}
}
b、A的列小于B的列,将A的三个元素直接存入C中
if(A[i+1]<B[j+1])
{
C[k]=A[i];
C[k+1]=A[i+1];
C[k+2]=A[i+2];
k=k+3;
i=i+3;
}
c、B的列小于A的列,将B的三个元素直接存入C中
if(A[i+1]>B[j+1])
{
C[k]=B[j];
C[k+1]=B[j+1];
C[k+2]=B[j+2];
k=k+3;
j=j+3;
}
d、A的行小于B的行,将A的三个元素直接存入C中
if(A[i]<B[j])
{
C[k]=A[i];
C[k+1]=A[i+1];
C[k+2]=A[i+2];
k=k+3;
i=i+3;
}
e、B的行小于A的行,将B的三个元素直接存入C中if(A[i]>B[j])
{
C[k]=B[j];
C[k+1]=B[j+1];
C[k+2]=B[j+2];
k=k+3;
j=j+3;
}
f、A结束B还有元素,将B的所有元素直接存入C中if(A[i]==-1)
while(B[j]!=-1)
{
C[k]=B[j];
C[k+1]=B[j+1];
C[k+2]=B[j+2];
k=k+3;
j=j+3;
}
g、B结束A还有元素,将A的所有元素直接存入C中if(B[i]==-1)
while(A[i]!=-1)
{
C[k]=A[i];
C[k+1]=A[i+1];
C[k+2]=A[i+2];
k=k+3;
i=i+3;
}
最后定义C[k]=-1,结束算法。
三、调试过程(测试数据设计与测试结果分析)
1、输入矩阵A和矩阵B
2、转存后的结果如下
3、相加后的结果
四、总结
1、设计中遇到的问题及解决过程
本次实验过程中,输入错误是必然存在的,这个错误在编译过程中可以很快解决。
在定义main()函数的过程中,我们之前定义了一个错误如下:
void main()
{
int E[m][n],F[m][n],A[max],B[max],C[max];
int i,j,k;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",E[i][j]);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d"F[i][j]);
CreateMatrix(E,A);
CreateMatrix(F,B);。
}
它的输出函数不能识别,正确的函数如下:
void main()
{
int E[m][n],F[m][n],A[max],B[max],C[max];
int i,j,k;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&E[i][j]);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&F[i][j]);
CreateMatrix(E,A);
CreateMatrix(F,B);。
}
2、设计中产生的错误及原因分析
粗心是造成输入错误的主要原因。
在算法的实现过程中,我们容易对算法的定义弄不清楚,或者少定义其中的一部分,这必然造成算法不能正常的实现。
这需要我们在编写算法的过程中对算法有一个很好的掌握,并且对算法的整个实现过程能够清晰。
在定义函数的过程中,这次没有对于类型定义的错误,不过我们还是需要对函数的定义有一个很好的掌握,才能很好的利用函数的定义来实现算法,以及整个程序的运行。
3、设计体会和收获
在这次实验中,我们充分的理解了矩阵的存储方式,掌握了稀疏矩阵的转换过程以及它的每种不同情况下的转换方式。
在这个过程中,我们还理解了稀疏矩阵的加法的实现方式,以及它的输出过程。
本次实验使我对函数的加法有个一个很清晰地认识,知道了加法的实现过程,以及加法在实现过程中的细节。
这种方式可以使我们很好的掌握算法的应用,以此推广到其它的算法中去。