课程设计报告稀疏矩阵的完全链表表示及其运算Word文档格式.docx
《课程设计报告稀疏矩阵的完全链表表示及其运算Word文档格式.docx》由会员分享,可在线阅读,更多相关《课程设计报告稀疏矩阵的完全链表表示及其运算Word文档格式.docx(31页珍藏版)》请在冰豆网上搜索。
两个稀疏矩阵相加
两个稀疏矩阵相减
两个稀疏矩阵相乘
稀疏矩阵的转置
【实现提示]
链表上的操作。
二、数据结构的选择和概要设计
(一)、问题分析
1、功能要求:
根据用户输入的矩阵,实现稀疏矩阵的求和运算,并输出结果。
4、菜单
具有选择功能的用户友好、菜单式系统,可以选择相应的功能来处理输入的数据。
三、详细设计和编码
1.设计表示
(1)函数调用关系图
1、相加2、相减3、相乘非零元OVERFLOW
(2)算法思想
稀疏矩阵的每个结点包含down,right,row,col和value五个域。
(3)主要编码
intCreate(CrossList&
M)
{
inti,j,k,m,n,t;
ElemTypee;
OLNode*p,*q;
printf("
请输入稀疏距阵的行数列数非零元的个数:
"
);
scanf("
%d%d%d"
&
m,&
n,&
t);
M.mu=m;
M.nu=n;
M.tu=t;
M.rhead=(OLink*)malloc((m+1)*sizeof(OLink));
if(!
M.rhead)
exit(OVERFLOW);
M.chead=(OLink*)malloc((n+1)*sizeof(OLink));
M.chead)
for(k=0;
k!
=m;
k++)//初始化行头指针
M.rhead[k]=NULL;
=n;
k++)//初始化列头指针
M.chead[k]=NULL;
请按任意次序输入%d个非零元的行列元素值:
\n"
M.tu);
k<
t;
k++)
{
i,&
j,&
e);
if(i>
m||j>
n)
你输入的元素不在矩阵中请检查重输:
}
else
p=(OLNode*)malloc(sizeof(OLNode));
p)
p->
i=i;
j=j;
e=e;
if(M.rhead[i]==NULL||M.rhead[i]->
j>
j)//p插入该行第一节点处
right=M.rhead[i];
M.rhead[i]=p;
else//寻找行表插入位置
for(q=M.rhead[i];
q->
right&
&
right->
j<
j;
q=q->
right);
right=q->
right;
//完成行插入
q->
right=p;
if(M.chead[j]==NULL||M.chead[j]->
i>
i)//p插入该列第一节点处
down=M.chead[j];
M.chead[j]=p;
else//寻找列表插入位置
for(q=M.chead[j];
down&
down->
i<
i;
down);
down=q->
down;
//完成列插入
down=p;
returnOK;
}
intPrint(CrossListM)
inti,j,k;
OLinkp;
intarray[100][100];
for(i=0;
i!
=M.mu;
i++)
for(j=0;
j!
=M.nu;
j++)
array[i][j]=0;
//初始化数组所需部分
p=M.chead[k];
while(p)
array[p->
i][p->
j]=p->
e;
//将非零元存入数组中
p=p->
if(j==M.nu-1)
cout<
<
array[i][j]<
endl;
"
;
//以矩阵的显示方式显示稀疏矩阵
intAdd(CrossListM,CrossListN,CrossList&
Q)
inti,k;
OLinkp,pq,pm,pn;
OLink*col;
Q.mu=M.mu;
//初始化Q
Q.nu=M.nu;
Q.tu=0;
Q.rhead=(OLink*)malloc((Q.mu+1)*sizeof(OLink));
Q.rhead)
Q.chead=(OLink*)malloc((Q.nu+1)*sizeof(OLink));
Q.chead)
=Q.mu;
k++)//初始化行
Q.rhead[k]=NULL;
=Q.nu;
k++)//初始化列
Q.chead[k]=NULL;
col=(OLink*)malloc((Q.nu+1)*sizeof(OLink));
//生成指向列的最后节点的数组
col)
k++)//赋初始值
col[k]=NULL;
i++)//按行序相加
pm=M.rhead[i];
pn=N.rhead[i];
while(pm&
pn)
if(pm->
pn->
j)//矩阵M当情前结点的列小于矩阵N当前结点的列
p=(OLink)malloc(sizeof(OLNode));
//生成Q的结点
Q.tu++;
//非零元个数+1
//赋值
j=pm->
e=pm->
right=NULL;
pm=pm->
//pm右移
elseif(pm->
j)
j=pn->
e=pn->
pn=pn->
e+pn->
e)//M,N当前结点的列相同并且两元素之和非零
//pm右移
//pn右移
else//两元素相加为零
continue;
if(Q.rhead[i]==NULL)
Q.rhead[i]=pq=p;
pq->
pq=pq->
if(Q.chead[p->
j]==NULL)
Q.chead[p->
j]=col[p->
j]=p;
col[p->
j]->
while(pm)//将矩阵M该行的剩余元素插入矩阵Q
while(pn)//将矩阵N该行的剩余元素插入矩阵Q
if(col[k])
col[k]->
down=NULL;
free(col);
CrossListNegative(CrossListM)
for(intj=0;
p=M.rhead[j];
e=-p->
//将非零元的值反号
return(M);
intMult(CrossListM,CrossListN,CrossList&
inti,j,e;
OLinkq,p0,q0,q1,q2;
if(M.nu!
=N.mu)
你输入的两个距阵不能进行此操作\n"
}
Q.nu=N.nu;
i++)//初始化行
Q.rhead[i]=NULL;
i++)//初始化列
Q.chead[i]=NULL;
p0=M.rhead[i];
q0=N.chead[j];
e=0;
while(p0&
q0)
if(q0->
p0->
q0=q0->
//列后移
elseif(q0->
p0=p0->
//行后移
e=e+p0->
e*q0->
//乘积累加
//行列后移
if(e)//e不为零则插入Q
q=(OLink)malloc(sizeof(OLNode));
q)
Q.rhead[i])
Q.rhead[i]=q1=q;
q1=q1->
right=q;
Q.chead[j])
Q.chead[j]=q;
q2=Q.chead[j];
while(q2->
down)
q2=q2->
q2->
down=q;
四、上机调试过程
1.调试过程中遇到的主要问题是如何解决的:
由于代码是仿照网上代码参照而写出来的,网上代码是c++编写的,所以部分代码需要改写成C语言,由于C++我们没学过,所以还要通过查询书籍和网络了解C++语言如何改写成C语言,1、coutendl;
语句等价于printf例:
cout<
你输入的是"
等价于printf("
2、cin;
语句等价于scanf例:
cin>
>
Select;
等价于scanf("
%d"
Select);
其中Select是int型3、c语言中变量的定义必须在函数的首部:
像这种的要把intj;
提出来
2.对设计和编码的回顾讨论和分析:
在设计方面,主要就是算法思想的设计,以及具体函数的设计运行。
在这方面,主要的算法设计思想倒不是特别的难想,主要是具体函数例如加法的函数的具体设计比较繁琐,耗费了较多时间。
而在编码方面,由于c语言的学习还是在大一下学期,所以对于相关知识已经有所遗忘,所以在编码的过程遇到了不少问题需要查阅书籍,尤其涉及到具体代码的编写,更是花费了不少时间来修正调试。
五、测试结果及其分析
1、改进设想:
对于运算的界面可以更加精美有条理性一些;
除此以外,可以给运算设计一个选择界面,用户可以选择进行计算和退出;
由于部分代码是参考网上案列c++编码的,我想把它改成C语言代码,丹改过来后,他总是报错,调试也找不来原因,null指没有声明,但在头文件stdio.h中已有null值得申明,最后自定义个null值得声明,还是不行,所以导致我的部分代码有些不理解,这好似一部分遗憾,希望通过以后的学习和学习中明白这些原因。
2、经验和体会:
十字链表作为存储结构表示随机稀疏矩阵,进行两矩阵的相加运算,所以首先要定义一个十字链表作为存储结构。
仅有此还是不够的,还需要定义指针来指向链表中的元素。
在开始的时候,老是得不到想象中的结果,通过几次的检查才发现问题出在对矩阵中的元素指向没有弄清楚,所以即使是相位置上的元素也没有处理好它们的相加问题。
这个实验从最初的设计到完成,出现了很多错误,通过最终的修正发现,其实犯的都是小错误,都是些指针的问题。
因为指针是我比较薄弱的环节。
我发现了这些问题,所以我就要进行弥补、查缺补漏。
通过这次课程设计,敦促我将过去学习过的知识进行了温习,知识只有多巩固,才能真正的理解与领悟。
六、用户使用说明
按提示进行相关操作。
1、先运行出来:
出现主界面
2、先选择你将要运算的功能,列如1、相加,然后输入你第一个稀疏矩阵的行、列、非零元的个数,接着输入非零元素的行、列和值;
输入第二个稀疏矩阵的行、列、非零元的个数,接着输入非零元素的行、列和值;
3、输入完成后,点击回车,它会显示出你所输入的第一个稀疏矩阵、第二个稀疏矩阵,以及它们相加后得到的稀疏矩阵。
一、源程序
#include<
stdio.h>
stdlib.h>
iostream.h>
process.h>
#defineOK1
#defineERROR0
#defineOVERFLOW-2
typedefintElemType;
structOLNode
inti,j;
//非零元所在行、列
//非零元值
OLNode*right,*down;
};
typedefOLNode*OLink;
structCrossList
OLink*rhead,*chead;
//行、列表头的头节点
intmu,nu,tu;
//矩阵的行、列和非零元个数
col