稀疏矩阵应用.docx

上传人:b****5 文档编号:6880237 上传时间:2023-01-12 格式:DOCX 页数:15 大小:146.82KB
下载 相关 举报
稀疏矩阵应用.docx_第1页
第1页 / 共15页
稀疏矩阵应用.docx_第2页
第2页 / 共15页
稀疏矩阵应用.docx_第3页
第3页 / 共15页
稀疏矩阵应用.docx_第4页
第4页 / 共15页
稀疏矩阵应用.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

稀疏矩阵应用.docx

《稀疏矩阵应用.docx》由会员分享,可在线阅读,更多相关《稀疏矩阵应用.docx(15页珍藏版)》请在冰豆网上搜索。

稀疏矩阵应用.docx

稀疏矩阵应用

稀疏矩阵应用

课题简介

课题及要求

稀疏矩阵应用(限1人完成)

设计要求:

实现三元组,十字链表下的稀疏矩阵的加、转、乘的实现。

(1)稀疏矩阵的存储

(2)稀疏矩阵加法

(3)矩阵乘法

(4)矩阵转置

课程任务分析

本课程设计主要实现在三元组存储结构与十字链表存储结构下输入稀疏矩阵,并对稀疏矩阵进行转置,相加,相乘操作,最后输出运算后的结果。

稀疏矩阵采用三元组和十字链表表示,并在两种不同的存储结构下,求两个具有相同行列数的稀疏矩阵A和B的相加矩阵C,并输出C;求出A的转置矩阵D,输出D;求两个稀疏矩阵A和B的相乘矩阵E,并输出E。

课程的意义

其意义是让咱们在学习完C、数据结构等课程基础上,掌握多维数组的逻辑结构和存储结构、掌握稀疏矩阵的紧缩存储及转置,相加,相乘等大体操作,并用不同的方式输出结果,进一步掌握设计、实现较大系统的完整进程,包括系统分析、编码设计、系统集成、和调试分析,熟练掌握数据结构的选择、设计、实现和操作方式,为进一步的应用开发打好基础。

程序分析

设计函数成立稀疏矩阵及初始化值和输出稀疏矩阵的值

本模块要求设计函数成立稀疏矩阵并初始化,包括在三元组结构下和十字链表结构下。

第一要概念两种不同的结构体类型,在创建稀疏矩阵时,需要设计两个不同的函数别离在三元组和十字链表下创建稀疏矩阵,在输入出现错误时,能够对错误进行判别处置,初始化稀疏矩阵都为空值,特别注意在十字链表下,对变量进行动态的地址分派。

在设计输出稀疏矩阵的值的函数时,也要针对两种不同的情形,别离编制函数,才能准确的输出稀疏矩阵。

在对稀疏矩阵进行初始化及输出值时,均只输出非零元素的值和它所在的所在行及所在列。

构造函数进行稀疏矩阵的转置并输出结果

本模块要求设计函数进行稀疏矩阵的转置并输出转置后的结果,由于对稀疏函数的转置只对一个矩阵进行操作,所以实现起来难度不是专门大,函数也比较容易编写。

在编写函数时,要先概念一个相应的结构体变量用于寄存转置后的矩阵,最后把此矩阵输出。

构造函数进行两个稀疏矩阵相加及相乘并输出最终的稀疏矩阵

本模块要求设计相加和相乘函数对两个矩阵进行运算,并输出最终的稀疏矩阵,在进行运算前,要对两个矩阵进行检查,看是不是相同类型的矩阵,因为两个矩阵相加要求两个矩阵必然是同一类型的矩阵,概念相应的矩阵类型用于寄存两个矩阵相加相乘后的结果矩阵,那个结果矩阵的行数列数需要综合多方面情形来肯定。

这四个函数也是整个程序的难点,需要灵活运用数组及指针的特点。

退出系统

本模块要求设置选项能随时结束程序的运行,本程序中采用exit(0)函数。

程序以用户和运算机的对话方式执行,即在运算机终端上显示“提示信息”以后,由用户在键盘上输入演示程序中需要的相关信息及命令。

概要设计

主界面设计

为了实此刻两种存储结构下对稀疏矩阵的多种算法功能的管理,第一设计一含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户交互式利用本系统。

本系统主控菜单运行界面如图1所示。

图1主界面图

存储结构设计

本系统采用三元组结构和十字链表结构存储稀疏矩阵的具体信息。

其中:

在三元组中,所有元素的信息用数组表示,每一个数组元素中包括有行下标(i),列下标(j)和对应的数值(e),它们是整型数据,全数的信息用在十字链表中,全数结点的信息用结构体(TSMatrix)包括,包括用数组(Tripledata[MAXSIZE])和总共的行数(mu),列数(nu)和非零元素的个数(tu)。

在十字链表下,头结点为指针数组的十字链表存储;每一个结点里面包括行下标(i),列下标(j)和对应的数值(e),它们是整型数据,还有两个指针(right)、(down),属于OLNode结构体。

全数的信息用结构体(crosslist)包括,包括指针数组(OLink*rhead和*chead)和总共的行数(mu),列数(nu)和非零元素的个数(tu)。

三元组结构体概念:

typedefstruct{

inti,j;

inte;

}Triple;

typedefstruct{

Tripledata[MAXSIZE];

intrpos[MAXSIZE+1];

intnu,mu,tu;

}TSMatrix;

十字链表结构体概念:

typedefstructOLNode{

inti,j;

inte;

structOLNode*right,*down;

}OLNode,*OLink;

typedefstruct{

intmu,nu,tu;

OLink*rhead,*chead;

}CrossList;

系统功能设计

本系统除要完成份别在三元组存储结构和在十字链表下实现稀疏矩阵的初始化功能外还设置了4个子功能菜单。

稀疏矩阵的成立及初始化在三元组存储结构下,由函数voidCreateSMatrix(TSMatrix&M)实现,在十字链表存储结构下,由函数voidCreateSMatix_OL(CrossList&M)依据读入的行数和列数和非零元素的个数,别离设定每一个非零元素的信息。

4个子功能的设计描述如下。

(1)稀疏矩阵的转置:

此功能在三元组存储结构下,由函数voidTransposeSMatrix(TSMatrixM,TSMatrix&T)实现,在十字链表存储结构下,由函数voidTurnSMatrix_OL(CrossList&M)实现。

当用户选择该功能,系统提示用户初始化一个矩阵,然后进行转置,最终输出结果。

(2)稀疏矩阵的加法:

此功能在三元组存储结构下,由函数voidAddTMatix(TSMatrixM,TSMatrixT,TSMatrix&S)实现,在十字链表存储结构下,由函数intSMatrix_ADD(CrossList*A,CrossList*B)实现。

当用户选择该功能,系统即提示用户初始化要进行加法的两个矩阵的信息。

然后进行加法,最后输出结果。

(3)稀疏矩阵的乘法:

此功能在三元组存储结构下,由函数intMultSMatrix(TSMatrixM,TSMatrixN,TSMatrix&Q)实现。

在十字链表存储结构下,由函数intMultSMatrix_OL(CrossListM,CrossListN,CrossList&Q)实现。

当用户选择该功能,系统提示输入要进行相乘的两个矩阵的详细信息。

然后进行相乘,最后取得结果。

(4)退出:

即退出稀疏矩阵的应用系统,由exit(0)函数实现。

当用户选择该功能,则退出该稀疏矩阵的应用系统。

●调试分析

系统运行主界面

系统运行主界面如图2所示:

图2主界面图

各子功能测试运行结果

(以三元组为例)

(1)稀疏矩阵的创建及初始化:

在主菜单下,用户输入1回车,是用三元组创建稀疏矩阵,按照屏幕提示初始化一个稀疏矩阵,按enter键,运行结果如图3所示。

图3三元组创建并初始化矩阵

(2)稀疏矩阵的转置:

用三元组创建稀疏矩阵后,用户输入1回车,便显示该矩阵的转置矩阵,运行结果如图4所示。

图4三元组稀疏矩阵转置结果示用意

(3)稀疏矩阵的相加:

用三元组创建并初始化一个稀疏矩阵后,输入2回车,按屏幕提示输入第二个同类型的稀疏矩阵,按enter键,运行结果如图5所示。

图5三元组稀疏矩阵相加结果示用意

(4)稀疏矩阵的相乘:

用三元组创建并初始化一个稀疏矩阵后,输入3回车,按屏幕提示输入第二个同类型的稀疏矩阵,按enter键,运行结果如图6所示。

图6三元组稀疏矩阵相乘结果示用意

(5)退出:

在主菜单下,用户输入3回车,或在下级菜单中输入4回车,退出程序。

运行结果如图7,图8。

图7主菜单退出程序图

图8下级菜单退出程序图

●总结

由于本程序要求用两种办法对稀疏矩阵进行运算,专门是用十字链表这种形式来对稀疏矩阵进行运算,是实现起来有很多困难,主要包括:

1、书上这种方面的东西不多,资料少,能够参考的东西不是很多;

2、用十字链表进行运算比较复杂,难度较大,需要对指针掌握较好;

3、在书写课程设计报告时,没有具体的模板,感觉无从下手。

针对上述困难,我通过网络,图书馆找资料,借鉴他人的以往的优秀的课程设计报告,和同窗们一路讨论,慢慢地解决自己的问题。

通过这次课程设计,使我对本学期学的《数据结构》有了更深的了解,也使自己的所学加倍牢固,并能够把更方面的知识综合起来运用。

附录:

程序源代码

#include<>

#include<>

#defineMAXSIZE100

intnum[100];

typedefstructOLNode{

inti,j;

inte;

structOLNode*right,*down;

}OLNode,*OLink;

typedefstruct{

intmu,nu,tu;

OLink*rhead,*chead;

}CrossList;,&[i].j,&[i].e);

if([i].i<=0)||[i].j<=0)){

printf("输入错误,请从头输入");

scanf("%d%d%d",&[i].i,&[i].j,&[i].e);

}];==col){

[q].i=[p].j;

[q].j=[p].i;

[q].e=[p].e;

q++;

}

},[mcount].j,[tcount].i,[tcount].j))

=[mcount].e;<[tcount].i或[mcount].j<[tcount].j

[q].i=[mcount].i;

[q].j=[mcount].j;=[tcount].e;>[tcount].i或[mcount].j>[tcount].j

[q].i=[tcount].i;

[q].j=[tcount].j;+[tcount].e;=ce;

[q].i=[mcount].i;

[q].j=[mcount].j;

q++;

mcount++;

tcount++;}

else{mcount++;

tcount++;}

break;

}}

while(mcount<={

[q].e=[mcount].e;

[q].i=[mcount].i;

[q].j=[mcount].j;

q++;

mcount++;}=[tcount].e;

[q].i=[tcount].i;

[q].j=[tcount].j;

q++;

tcount++;

};

if(brow

elset=+1;

for(q=[brow];q

{ccol=[q].j;

ctemp[ccol]+=[p].e*[q].e;=arow,[].j=ccol,[].e=ctemp[ccol];

}

}

}

}

return1;

}==col)printf("%4d%4d%4d\n",[p].i,[p].j,[p].e);

}//三元组显示

voidTurnSMatrix_OL(CrossList&M){

intcol,row;//概念循环变量

OLinkp,q;//概念OLink结构类型变量

for(col=1;col<=;col++)//通过循环,把非零元素的行数与列数进行互换,实现转置

{q=p=[col];

while(q){

row=p->i;

p->i=p->j;

p->j=row;

q=p->right;

p->right=p->down;

p->down=q;

}

}

}//十字链表转置

intSMatrix_ADD(CrossList*A,CrossList*B){

OLNode*pa,*pb,*pre,*p,*cp[100];//概念OLNode类型的变量

inti,j,t;

t=A->tu+B->tu;

for(j=1;j<=A->nu;j++)cp[j]=A->chead[j];//将A矩阵的列表头指针赋给cp数组

for(i=1;i<=A->mu;i++){

pa=A->rhead[i];

pb=B->rhead[i];//将A,B矩阵的行表头指针别离赋给pa,pb

pre=NULL;

while(pb){//当pb不等于零

if(pa==NULL||pa->j>pb->j){

p=(OLink)malloc(sizeof(OLNode));//给p动态分派空间

if(!

pre)A->rhead[i]=p;

elsepre->right=p;

p->right=pa;

pre=p;

p->i=i;p->j=pb->j;p->e=pb->e;

if(!

A->chead[p->j]){

A->chead[p->j]=cp[p->j]=p;

p->down=NULL;

}//若是A->chead[p->j]不等于零,则把p赋给它及cp[p->j]

else{

cp[p->j]->down=p;

cp[p->j]=p;

}

pb=pb->right;

}//不然把p赋给cp[p->j]

elseif(pa->jj){pre=pa;

pa=pa->right;}

elseif(pa->e+pb->e){

t--;

pa->e+=pb->e;

pre=pa;

pa=pa->right;

pb=pb->right;}

else{t=t-2;

if(!

pre)A->rhead[i]=pa->right;

elsepre->right=pa->right;

p=pa;pa=pa->right;

if(A->chead[p->j]==p)A->chead[p->j]=cp[p->j]=p->down;

elsecp[p->j]->down=p->down;

free(p);

pb=pb->right;

}

}

}

A->mu=A->mu>B->mu?

A->mu:

B->mu;

A->nu=A->nu>B->nu?

A->nu:

B->nu;//A的行与列为A及B当中较大的一个

return1;

}//十字链表相加

intMultSMatrix_OL(CrossListM,CrossListN,CrossList&Q)

{

inti,j,e;//中间变量

OLinkp0,q0,p,pl,pla;//中间变量

if!

=//检查稀疏矩阵M的列数和N的行数是不是对应相等

{

printf("稀疏矩阵A的列数和B的行数不相等,不能相乘。

\n");

return0;

}

=,=,=0;

if(!

=(OLink*)malloc(+1)*sizeof(OLink))))exit(-2);

if(!

=(OLink*)malloc(+1)*sizeof(OLink))))exit(-2);

for(i=1;i<=;i++)[i]=NULL;

for(i=1;i<=;i++)[i]=NULL;

//相乘

for(i=1;i<=;i++)

for(j=1;j<=;j++)

{

p0=[i],q0=[j],e=0;

while(p0&&q0)//M第i行和N第j列有元素

{if(p0->j>q0->i)q0=q0->down;//M的列大于N的行,则N的列指针后移

elseif(p0->ji)p0=p0->right;//M的列小于N的行,则M的行指针右移

else{//M的行等于N的列

e+=p0->e*q0->e;//乘积累加

q0=q0->down,p0=p0->right;//移动指针

}

}

if(e)//乘积不为

{if(!

(p=(OLink)malloc(sizeof(OLNode))))exit(-2);

++;//非零元素增加

p->i=i,p->j=j,p->e=e,p->right=NULL,p->down=NULL;//赋值,指针后移

//将p插入十字链表,行插入

if[i]==NULL)//若p为该行的第个结点

[i]=pl=p;//p插在该行的表头且pl指向p(该行的最后一个结点)

elsepl->right=p,pl=p;//插在pl所指结点以后,pl右移

//列插入

if[j]==NULL)//若p为该列的第一个结点

[j]=p;//该列的表头指向p

else{//插在列表尾

pla=[j];//pla指向j行的第个结点

while(pla->down)pla=pla->down;//pla指向j行最后一个结点

pla->down=p;

}

}

}

return1;

}//十字链表相乘

intShowMAtrix(CrossList*A){

intcol;

OLinkp;

for(col=1;col<=A->mu;col++)if(A->rhead[col]){p=A->rhead[col];

while(p){printf("%3d%3d%3d\n",p->i,p->j,p->e);p=p->right;}

}

return1;

}//十字链表显示

voidmain(){

intn,i;

TSMatrixM,T,S;

CrossListMM,TT,SS;

printf("***稀疏矩阵应用***");

printf("\n请你选择创建稀疏矩阵的方式:

\n1:

用三元组创建稀疏矩阵\n2:

用十字链表创建稀疏矩阵\n3:

退出程序");

printf("\n");

scanf("%d",&n);

switch(n){

case1:

CreateSMatrix(M);

printf("您输入的稀疏矩阵为(只列出非零元素):

\n行列大小\n");

ShowTMatrix(M);

printf("已经选择三元组创建稀疏矩阵,请选择操作:

\n1:

稀疏矩阵转置\n2:

稀疏矩阵相加\n3:

稀疏矩阵相乘\n4:

退出程序\n");

scanf("%d",&i);

switch(i){

case1:

TransposeSMatrix(M,T);

printf("转置后的矩阵为(只列出非零元素):

\n行列大小\n");

ShowTMatrix(T);

break;

case2:

printf("请你输入另一个稀疏矩阵:

");

CreateSMatrix(T);

AddTMatix(M,T,S);

printf("相加后的矩阵为(只列出非零元素):

\n行列大小\n");

ShowTMatrix(S);

break;

case3:

printf("请你输入另一个稀疏矩阵:

");

CreateSMatrix(T);

MultSMatrix(M,T,S);

printf("相乘后的矩阵为(只列出非零元素):

\n行列大小\n");

ShowTMatrix(S);

break;

case4:

exit(0);};break;

case2:

{CreateSMatix_OL(MM);

printf("您输入的稀疏矩阵为(只列出非零元素):

\n行列大小\n");

ShowMAtrix(&MM);

printf("已经选择十字链表创建稀疏矩阵,请选择操作:

\n1:

稀疏矩阵转置\n2:

稀疏矩阵相加\n3:

稀疏矩阵相乘\n4:

退出程序\n");

scanf("%d",&i);

switch(i){

case1:

TurnSMatrix_OL(MM);

printf("转置后的矩阵为(只列出非零元素):

\n行列大小\n");

ShowMAtrix(&MM);

break;

case2:

printf("请你输入另一个稀疏矩阵:

");

CreateSMatix_OL(TT);

SMatrix_ADD(&MM,&TT);

printf("相加后的矩阵为(只列出非零元素):

\n行列大小\n");

ShowMAtrix(&MM);break;

case3:

printf("请你输入另一个稀疏矩阵:

");

CreateSMatix_OL(TT);

MultSMatrix_OL(MM,TT,SS);

printf("相乘后的矩阵为(只列出非零元素):

\n行列大小\n");

ShowMAtrix(&SS);break;

case4:

exit(0);

}};break;

case3:

exit(0);

default:

printf("erorr");

}

}

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1