数据结构三元组稀疏矩阵完整版实用资料.docx
《数据结构三元组稀疏矩阵完整版实用资料.docx》由会员分享,可在线阅读,更多相关《数据结构三元组稀疏矩阵完整版实用资料.docx(51页珍藏版)》请在冰豆网上搜索。
![数据结构三元组稀疏矩阵完整版实用资料.docx](https://file1.bdocx.com/fileroot1/2023-6/25/9d2dd3da-4a3e-4325-951a-6ae1d4f795a8/9d2dd3da-4a3e-4325-951a-6ae1d4f795a81.gif)
数据结构三元组稀疏矩阵完整版实用资料
数据结构三元组稀疏矩阵(完整版)实用资料
(可以直接使用,可编辑完整版实用资料,欢迎下载)
一、课程设计的目的
1.将C++语言理论基础实例化。
2.掌握关于编程的技巧和方法。
3.培养解决综合性实际问题的能力。
二、课程设计任务
题目:
稀疏矩阵A,B的和
题目要求:
稀疏矩阵A,B用三元组顺序表存储。
三元组表C存放结果矩阵A,B的和存到C中。
题目:
用三元组C存放以三元组顺序表做存储结构的稀疏矩阵A,B的和
一、题目分析
三元组表C是结果矩阵,其中元素仍行优先排列,
按元素的行列去找A中的三元组,若有,则加入C,同时,这个元素如果在B中也有,则加上B的这个元素值,否则这个值就不变;
如果A中没有,则找B,有则插入C,无则查找下一个矩阵元素。
两个稀疏矩阵的非零元素按三元组表形式存放,
二、程序代码
#include
#include
#definemax10
typedefstruct
{inti,j;
intv;
}spnode;
typedefstruct
{intmu,nu,tu;
spnodedata[max];
}spmatrix;
addmatrix(spmatrix*a,spmatrix*b)
{spmatrix*c;
intp=0;q=0;col;c=(spmatrix*)malloc(sizeof(spmatrix));c->mu=a->mu;
c->nu=a->nu;c->tu=0;
while(ptu&&qtu)
{if((a->data[p].i==B->data[q].i)&&(A->data[p].j==B->data[q].j)){col=a->data[p].v+B->data[q].v;if(col!
=0){c->data[c->tu].i=a->data[p].i;
c->data[c->tu].j=a->data[p].j;
c->data[c->tu++].v=col;
}
p++;
q++;}
if((a->data[p].i==b->data[q].i)&&(a->data[k].jdata[l].j))
{c->data[c->tu].i=a->data[p].i;
c->data[c->tu].j=a->data[p].j;
c->data[c->tu++].v=a->data[p].v;
p++;
}
if((a->data[p].i==b->data[q].i)&&(a->data[k].j>b->data[l].j))
{c->data[c->tu].i=a->data[p].i;
c->data[c->tu].j=a->data[p].j;
c->data[c->tu++].v=a->data[p].v;
q++;}
}
while(ptu)
{c->data[c->tu].i=a->data[p].i;c->data[c->tu].j=a->data[p].j;c->data[c->tu++].v=a->data[p].v;p++;
}
while(qtu)
{c->data[c->tu].i=b->data[q].i;c->data[c->tu].j=b->data[q].j;c->data[c->tu++].v=b->data[q].v;q++;
}
}
voidSetmatrix(SPMatrix*p)
{
intn;cout<<"请输入矩阵行数、列数及非0元个数"<>p->mu>>P->nu>>p->tu;
cout<<"三元组表"<tu;n++)
cin>>p->data[n].i>>p->data[n].j>>p->data[n].v;}
voidmain()
{
spmatrixa;
spmatrixb;
inti,j,k=1;
spmatrix*c;
}Setmatrix(&a);Setmatrix(&b);c=addmatrix(&a,&b);cout<<"三元组表c"<mu;++i){for(j=1;j<=c->nu;++j){if(pc->data[k].i==i&&pc->data[k].j==j){cout<data[k].v);k++;}}}free(c);
三、运行结果
四、总结
三元组存储的矩阵的加法关键在于算法的分析。
而数据结构比较C语言层次性更强。
写算法的时候不是很难,就是对主函数的写法有点模糊。
总体上讲,实践将理论具体化,也更容易进一步的学习。
计算机科学技术学院
学生课程设计(论文)
题目:
学生姓名:
学号:
所在院(系):
专业:
班级:
指导教师:
职称:
年月日
计算机科学技术学院本科学生课程设计任务书
注:
任务书由指导教师填写。
课程设计(论文)指导教师成绩评定表
稀疏矩阵的操作
1.课程设计的目的
本课程设计是为了配合《数据结构》课程的开设,通过设计一完整的程序,使学生掌握数据结构的应用、算法的编写、类C语言的算法转换成C程序并用TC上机调试的基本方法。
利用三元组实现稀疏矩阵的有关算法。
2.问题描述
2.1稀疏矩阵采用三元组表示,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C。
2.2求出A的转置矩阵D,输出D。
3.基本要求
稀疏矩阵是指那些多数元素为零的矩阵。
利用“稀疏”特点进行存储和计算可以大大节省存储空间,提高计算效率。
实现一个能进行稀疏矩阵基本运算的运算器。
以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、相减和相乘的运算。
稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则通常以阵列形式列出。
4.结构设计
4.1.以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两个矩阵相加、相减和相乘的运算。
4.2.稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则通常以阵列形式列出。
4.3.首先应输入矩阵的行数和列数,并判别给出的两个矩阵的行、列数对于所要求作的运算是否相匹配。
可设矩阵的行数和列数均不超过20。
4.4.程序可以对三元组的输入顺序加以限制,例如,按行优先。
注意研究教材的算法,以便提高计算效率。
5.在用三元组表示稀疏矩阵时,相加或相减所得结果矩阵应该另生成,乘积矩阵也可用二维数组存放
5.算法思想
5.1.主函数设置循环和选择语句进行运算循环和选择,进行稀疏矩阵的加法,减法,乘法,转置和是否继续运算5个分支开关进行运算选择。
5.2.设置函数分别实现稀疏矩阵的输入,输出,加法,减法,乘法。
5.3.在数组结构体中设置存放每行第一个非零元在其数组存储结构单元的位置的存储单元,若该行无非零元,则存为0
6.模块划分
6.1typedefstruct存放各行第一个非零元在存储数组中的位置,若该行无非零元,则其rpos[]值为零
6.2createsmatrix(rlsmatrix*M)矩阵输入函数,输入各行非零元及其在矩阵中的行列数
6.3FasttransposeRLSMatrix(RLSMatrixM,RLSMatrix*Q)矩阵快速转置
6.4HeRLSMatrix(RLSMatrix*M,RLSMatrix*N,RLSMatrix*Q)矩阵求和
6.5ChaRLSMatrix(RLSMatrix*M,RLSMatrix*N,RLSMatrix*Q)矩阵求差
6.6JiRLSMatrix(RLSMatrixM,RLSMatrixN,RLSMatrix*Q)矩阵求积
7.算法实现
7.1首先定义非零元个数的最大值和存放各行第一个非零元在存储数组中的位置#include
#defineMAXSIZE100/*非零元个数的最大值*/
typedefstructtriple
{
inti,j;/*行下标,列下标*/
inte;/*非零元素值*/
}triple;
typedefstructtsmatrix
{
tripledata[MAXSIZE+1];/*非零元三元组表,data[0]未用*/
intmu,nu,tu;/*矩阵的行数、列数和非零元个数*/
/*各列第一个非零元的位置表rpos[0]未用*/
}rlsmatrix;
7.2创建稀疏矩阵矩阵的行数,列数,和非零元素的个数并按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值。
createsmatrix(rlsmatrix*M)
{/*创建稀疏矩阵M*/
inte,i,m,n;
M->data[0].i=0;/*为以下比较顺序做准备*/
printf("请输入矩阵的行数,列数,和非零元素的个数:
");
scanf("%d",&M->mu);scanf("%d",&M->nu);scanf("%d",&M->tu);
for(i=1;i<=M->tu;i++)
{
printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值:
",i,M->mu,M->nu);scanf("%d",&m);scanf("%d",&n);scanf("%d",&e);
if(m<1||m>M->mu||n<1||n>M->nu)/*行或列超出范围*/
{printf("行或列超出范围");getch();exit();}
if(mdata[i-1].i||m==M->data[i-1].i&&n<=M->data[i-1].j)/*行或列的顺序有错*/
{printf("行或列的顺序有错");getch();exit();}
M->data[i].i=m;
M->data[i].j=n;
M->data[i].e=e;
}
}
7.3求矩阵的快速转置
cpos为存放每列的第一个非零元素的地址,temp为中间变量对cpos对初始化,判断初值
为0则为cpos赋值,然后进行转置。
voidtransposesmatrix(rlsmatrixM,rlsmatrix*T)
{/*cpos存放每列的第一个非零元素的地址,temp中间变量*/
inti,m,*cpos,*temp,k=0;
T->mu=M.nu;
T->nu=M.mu;
T->tu=M.tu;
cpos=(int*)malloc(M.mu*sizeof(int));
if(cpos==NULL)exit();
temp=(int*)malloc(M.mu*sizeof(int));
if(temp==NULL)exit();
/*对cpos对初始化,初值为0*/
*(cpos+1)=0;
for(i=1;i<=M.nu;i++)
{
for(m=1;m<=M.tu;m++)
{
if(M.data[m].j==i)
k++;
}
temp[i]=k;
if(i==1&&k!
=0)
*(cpos+i)=1;/*为cpos赋值*/
if(i>1)
*(cpos+i)=*(temp+i-1)+1;
}
free(temp);
for(i=1;i<=M.tu;i++)/*进行转置*/
{T->data[*(cpos+M.data[i].j)].i=M.data[i].j;
T->data[*(cpos+M.data[i].j)].j=M.data[i].i;
T->data[*(cpos+M.data[i].j)].e=M.data[i].e;
(*(cpos+M.data[i].j))++;}
free(cpos);
}
7.3矩阵的相乘
设置两个指针,分别指向M,N的第一个非零元位置,移动指针进行比较,得出相加后的新矩阵非零元。
定义Qe为矩阵Q的临时数组,矩阵Q的第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。
multsmatrix(rlsmatrixM,rlsmatrixN,rlsmatrix*T)
{
inti,j,Qn=0;
int*Qe;
if(M.nu!
=N.mu)
{printf("两矩阵无法相乘");getch();exit();}
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;
}
free(Qe);
T->tu=Qn;
return;
}
7.4矩阵的相加
编写一个求两个对称矩阵相加运算的函数。
设对称矩阵的数据元素为整数类型,对称矩阵采用压缩存储方法存储,要求和矩阵采用非压缩方法存储。
设置两个指针,分别指向M,N的第一个非零元位置,移动指针进行比较,得出相加后的新矩阵非零元计算各行第一个非零元素在存储数组中的位置,若该行无非零元,则rpos[]值为零。
HeRLSMatrix(RLSMatrix*M,RLSMatrix*N,RLSMatrix*Q)
{//矩阵求和函数
if((*M).mu!
=(*N).mu||(*M).nu!
=(*N).nu)
{printf("不满足矩阵相加的条件!
");return0;}
intk=1;Triple*p,*q;
元
//设置两个指针,分别指向M,N的第一个非零元位置,移动指针进行比较,得出相加后的新矩阵非零p=&(*M).data[1];q=&(*N).data[1];while(p<(*M).data+(*M).tu+1&&q<(*N).data+(*N).tu+1)if((*p).i<=(*q).i)if((*p).i<(*q).i){(*Q).data[k].i=(*p).i;(*Q).data[k].j=(*p).j;(*Q).data[k].e=(*p).e;k++;p++;}elseif((*p).j<=(*q).j)if((*p).j<(*q).j){(*Q).data[k].i=(*p).i;(*Q).data[k].j=(*p).j;(*Q).data[k].e=(*p).e;k++;p++;}{(*Q).data[k].i=(*p).i;(*Q).data[k].j=(*p).j;(*Q).data[k].e=(*p).e+(*q).e;k++;p++;q++;}elseelse{(*Q).data[k].i=(*q).i;(*Q).data[k].j=(*q).j;(*Q).data[k].e=(*q).e;k++;q++;}else{(*Q).data[k].i=(*q).i;(*Q).data[k].j=(*q).j;(*Q).data[k].e=(*q).e;k++;q++;}
if(p<=(*M).data+(*M).tu)
while(p<=(*M).data+(*M).tu){(*Q).data[k].i=(*p).i;(*Q).data[k].j=(*p).j;
(*Q).data[k].e=(*p).e;
k++;p++;
}
if(q<=(*N).data+(*N).tu)
while(q<=(*N).data+(*N).tu){
(*Q).data[k].i=(*q).i;(*Q).data[k].j=(*q).j;(*Q).data[k].e=(*q).e;k++;q++;}(*Q).mu=(*M).mu;(*Q).nu=(*M).nu;(*Q).tu=k-1;
//计算各行第一个非零元素在存储数组中的位置//若该行无非零元,则rpos[]值为零
}for(k=1;k<=(*Q).tu;k++)++num[(*Q).data[k].i];for(row=2;row<=(*Q).mu;row++)cpot[row]=cpot[row-1]+num[row-1];for(row=1;row<=(*Q).mu;row++){}if(cpot[row]<=(*Q).tu)if((*Q).data[cpot[row]].i==row){(*Q).rpos[row]=cpot[row];}else(*Q).rpos[row]=0;else(*Q).rpos[row]=0;intnum[(*Q).mu+1],row,cpot[(*Q).mu+1];cpot[1]=1;for(k=1;k<=(*Q).mu;k++)num[k]=0;
8.系统运行结果
图1输入第一个矩阵A
图2输入第二个矩阵B两个矩阵的和
图3矩阵A的转置矩阵D
9.心得体会
通过一周的课程设计使我对数据结构有了更深的理解,对以前学习中不明白的,不理解的都有了进一步的理解。
在实际操作中遇到了很多困难,但通过找资料,请教同学和老师,使我的动手能力和沟通能力都有了提高。
在整个课程设计中总是在编写程序中发生错误,有时会很没耐性,但都被我一一克服了,编程一定要有耐心,同时还有认真仔细,尽量保证不出现错误。
编程要有条理,不仅使自己要看懂,别人也能看懂,这样有利于程序的改正。
在做完这个课程设计时,心里有种说不出来的高兴,自己动手完成的设计有一种成就感,增强了自己的自信心,我相信在今后的学习中,我会保持这种良好的心情投入到各科的学习中,使我的成绩不断提高。
10.参考文献
[1]严蔚敏吴伟名编著,《数据结构》[M].,清华大学出版社,2001年1月20-25
[2]张颖江胡燕主编,《C语言程序设计》[M].,科学出版社,1998年7月46-80
[3]殷人昆,《数据结构》[M].,清华大学出版社,2001年3月120-169
[4]徐孝凯,《数据结构实用教程》[M].,清华大学出版社,1999年12月47-80
[5]AdamDrozdek(美),《数据结构与算法》[M].,机械工业出版社,2003年7月69-89
11.附录源程序清单
#include
#defineMAXSIZE100/*非零元个数的最大值*/
typedefstructtriple
{
inti,j;/*行下标,列下标*/
inte;/*非零元素值*/
}triple;
typedefstructtsmatrix
{
tripledata[MAXSIZE+1];/*非零元三元组表,data[0]未用*/
intmu,nu,tu;/*矩阵的行数、列数和非零元个数*/
/*各列第一个非零元的位置表rpos[0]未用*/
}rlsmatrix;
createsmatrix(rlsmatrix*M)
{/*创建稀疏矩阵M*/
inte,i,m,n;
M->data[0].i=0;/*为以下比较顺序做准备*/
printf("请输入矩阵的行数,列数,和非零元素的个数:
");
scanf("%d",&M->mu);scanf("%d",&M->nu);scanf("%d",&M->tu);
for(i=1;i<=M->tu;i++)
{
printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),列(1~%d),元素值:
",i,M->mu,M->nu);scanf("%d",&m);scanf("%d",&n);scanf("%d",&e);
if(m<1||m>M->mu||n<1||n>M->nu)/*行或列超出范围*/
{printf("行或列超出范围");getch();exit();}
if(mdata[i-1].i||m==M->data[i-1].i&&n<=M->data[i-1].j)/*行或列的顺序有错*/
{printf("行或列的顺序有错");getch();exit();}
M->data[i].i=m;
M->data[i].j=n;
M->data[i].e=e;
}
}
voidtransposesmatrix(rlsmatrixM,rlsmatrix*T)
{/*cpos存放每列的第一个非零元素的地址,temp中间变量*/
inti,m,*cpos,*temp,k=0;
T->mu=M.nu;
T->nu=M.mu;
T->tu=M.tu;
cpos=(int*)malloc(M.mu*sizeof(int));
if(cpos==NULL)exit();
temp=(int*)malloc(M.mu*sizeof(int));
if(temp==NULL)exit();
/*对cpos对初始化,初值为0*/
*(cpos+1)=0;
for(i=1;i<=M.nu;i++)
{
for(m=1;m<=M.tu;m++)
{
if(M.data[m].j==i)
k++;
}
temp[i]=k;
if(i==1&&k!
=0)
*(cpos+i)=1;