课程设计报告 十字链表文档格式.docx
- 文档编号:21667241
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:17
- 大小:114.34KB
课程设计报告 十字链表文档格式.docx
《课程设计报告 十字链表文档格式.docx》由会员分享,可在线阅读,更多相关《课程设计报告 十字链表文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
若定义变量:
Crosslist*C;
则一个十字链表由一个C指针唯一确定。
为实现上述功能:
①建立两个十字链表存储两个稀疏矩阵。
②判断该两个稀疏矩阵是否满足相加条件。
若满足,将两稀疏矩阵相加并输出相加后的结果;
否则进入选择菜单,重新输入矩阵或者退出程序。
若选择重新输入矩阵,则继续执行上面的①②。
程序流程框图如图4所示。
3、详细设计和编码
本程序主要实现两稀疏矩阵的相加,因此首先依次创建两个空十字链表,将输入的两稀疏矩阵的非0元素依次插入相应的空十字链表。
在利用十字链表存储稀疏矩阵时,由用户输入的稀疏矩阵的行(m)、列数(n)来确定十字链表的行与列表头指针数组的大小(Lnode*rhead[m],*chead[n])。
当用户输入一个稀疏矩阵后,由元素的输入顺序序号来求出该元素在矩阵中所在的行号和列号,并将非0元素插入十字链表中(在此用指针C确定一个十字链表,方便后面说明):
for(k=0;
k<
C->
m*C->
n;
k++){
scanf("
%d"
&
d);
a=k/C->
m;
//求行号
b=k%C->
//求列号
if(d!
=0){}//将非0元素插入十字链表中
}
将非0元素的所有信息生成相应的结点L(结点结构如图3所示),并根据其行号和列号将该结点插入相应的行链表和列链表中。
将该结点插入相应的行链表中时,首先查找到插入位置:
如果相应的行链表为空,或者当前结点的列号比该行链表中第一个结点的列号小,则将该结点作为首元素结点插入到该行链表中:
booldone;
done=(C->
rhead[L->
i]==NULL||L->
j<
i]->
j);
if(done){
L->
rptr=C->
i];
i]=L;
}
否则,查找该行链表中的各结点的列号,将该结点按列号的顺序插入到该行链表中。
else{
p=C->
q=p->
rptr;
while(q!
=NULL){
if(L->
q->
j)
break;
p=q;
q=p->
}
p->
rptr=L;
rptr=q;
将该结点插入相应的列链表中时,方法同上:
如果相应的列链表为空,或者当前结点的行号比该列链表中第一个结点的行号小,则将该结点作为首元素结点插入到该列链表中;
否则,查找该列链表中的各结点的行号,将该结点按行号的顺序插入到该列链表中。
两稀疏矩阵相加时,首先根据表示两稀疏矩阵的十字链表(用指针A和B表示)中的行号和列号信息来判断该两稀疏矩阵是否满足相加条件,若满足,进行相加运算;
否则,进入选择菜单:
重新输入矩阵和退出。
满足相加条件时(即两稀疏矩阵同行同列),逐个比较两个稀疏矩阵对应行a的行链表A->
rhead[a]与B->
rhead[a]上的每个结点*pl和*ql:
由于两矩阵同行,且行链表有多个,因此用一个for循环来控制两指针指向属于同行的行链表并实现逐行比较相加。
for(a=0;
a<
a++){
pl=A->
rhead[a];
ql=B->
}
初始化指针pl和ql后,逐个比较行链表A->
rhead[a]与B->
rhead[a]上的每一个结点,直到两行链表中的所有非0元素结点均比较完毕:
⑴当A->
rhead[a]都为空时,若本行不是最后一行,则继续比较下一行。
⑵当A->
rhead[a]都不为空时,比较结点*p1与结点*ql的列号:
①若结点*p1的列号等于结点*ql的列号,则将结点*p1的值与结点*ql的值相加,如果相加的结果不等于0,则将结果信息生成的结点插入到一个新十字链表C中,方法同存储稀疏矩阵时向十字链表中插入非0元素结点,并修改指针pl和ql,将其指向下一个结点。
如果相加的结果等于0,只需将指针pl和ql指向本身结点指向的下一个结点。
pl=pl->
ql=ql->
②若结点*p1的列号小于结点*ql的列号,则直接将结点*p1插入到十字链表C中(方法同上),并修改指针p1,将其指向下一个结点。
③若结点*p1的列号大于结点*ql的列号,则直接将结点*ql插入到十字链表C中(方法同上),并修改指针ql,将其指向下一个结点。
⑶当A->
rhead[a]其中一个为空时,若结点*p1为空,则将结点*ql及其后面连接的所有结点插入十字链表C中。
若结点*ql为空,则将结点*p1及其后面连接的所有结点插入十字链表C中。
4、上机调试
1、错误分析及改正:
在本程序中将两矩阵进行逐行相加时,如输入的两个矩阵中有属于同一行的元素为2312和4000,运行程序后得到的相加结果为6000,而正确的结果应该为6312。
程序中将上面两行元素进行相加时,首先分别从值为2的结点和值为4的结点的列号开始进行比较,由于这两个结点同行同列,所以将相加的结果插入一个十字链表中,然后它们下一个结点的列号。
但由上可知,值为4的结点没有下一个结点,而原来程序中没有对这种情况的处理,直接比较下一行,因此导致相加结果为6000。
出现上述情况后,对原来程序进行改进,增加处理此种特殊情况,增加代码如下:
while(pl!
=NULL){//A矩阵中该行链表中的结点未比较完
x=pl;
pl=pl->
C=Insertlist(x,C);
while(ql!
=NULL){//B矩阵中该行链表中的结点未比较完
x=ql;
ql=ql->
2、时间、空间性能分析(以下出现的m表示一个矩阵的行数,n表示一个矩阵的列数):
本程序需要三个十字链表来存储进行相加的两稀疏矩阵和相加后的结果矩阵,每个十字链表都有行、列表头指针数组,所以最好情况下需要3*(m+n)个表头指针结点,最坏情况下需要3*(m+n)个表头指针结点和3*(m*n)链表结点。
在成功申请十字链表内存空间后,都先需要对其行、列表头指针结点进行初始化,因此初始化的时间性能为O(m+n)。
将稀疏矩阵存入十字链表中和将两矩阵进行相加过程都是对每个元素进行判断插入,所以最好情况下,两稀疏矩阵的元素都为0,此时只需判断,不需要进行插入操作。
最坏情况下,两稀疏矩阵的元素都不为0,此时时间性能为O(m*n)。
5、测试结果及其分析
六、用户使用说明
用户运行本程序后,界面会出现提示性的语句,如“请输入矩阵A的行数、列数:
”、“请输入矩阵”等,输入矩阵时按矩阵的书面形式输入即可。
7、参考文献
[1]王昆仑,李红.数据结构与算法.北京:
中国铁道出版社,2006年5月。
八、附录
#include<
stdio.h>
stdlib.h>
#defineM10//行
#defineN10//列
#definezero0
typedefstructnode{
//行号、列号、数值
typedefstruct{
Crosslist*Insertlist(Lnode*L,Crosslist*C){//将结点L插入十字链表C中
Lnode*p,*q;
booldone;
done=(C->
//如果该行链表为空,或者当前结点的列号比该行链表中第一个结点的列号小,则将该
//结点作为首元素结点插入到该行链表中
if(done){
L->
C->
//否则,查找该行链表中的各结点的列号,按将该结点按列号的顺序插入到该行链表中
else{
p=C->
q=p->
while(q!
p->
chead[L->
j]==NULL||L->
i<
j]->
i);
//如果该列链表为空,或者当前结点的行号比该行链表中第一个结点的行号小,则将该
//结点作为首元素结点插入到该列链表中
if(done){
cptr=C->
j];
C->
j]=L;
//否则,查找该列链表中的各结点的行号,按将该结点按行号的顺序插入到该列链表中
cptr;
i)
cptr=L;
cptr=q;
returnC;
Crosslist*Setcrosslist(){//创建十字链表
Crosslist*C;
Lnode*L;
intk,a,b,d;
C=(Crosslist*)malloc(sizeof(Crosslist));
for(k=0;
M;
k++)
rhead[k]=NULL;
N;
chead[k]=NULL;
printf("
行数、列数:
\n"
);
scanf("
%d%d"
m,&
n);
请输入矩阵:
if(d!
=0){//将非0元素插入十字链表中
L=(Lnode*)malloc(sizeof(Lnode));
L->
i=a;
j=b;
data=d;
rptr=L->
cptr=NULL;
C=Insertlist(L,C);
voidCrosslistout(Crosslist*C){//十字链表输出
inta,b;
Lnode*p;
for(a=0;
for(b=0;
b<
b++){
if(p!
=NULL&
&
j==b){//若该行该列有非0元素,输出该非0元素的值
printf("
%-5d"
p->
data);
p=p->
}
else//否则输出0
printf("
zero);
printf("
Crosslist*Matrixplus(Crosslist*A,Crosslist*B){//两个矩阵相加
intresult,a;
Lnode*pl,*ql,*L;
a++)
rhead[a]=NULL;
chead[a]=NULL;
m=A->
n=A->
while(pl!
ql!
if(pl->
j==ql->
j){//同行同列
result=pl->
data+ql->
data;
if(result!
=0){//相加后结果不为0
L=(Lnode*)malloc(sizeof(Lnode));
L->
i=pl->
i;
j=pl->
j;
data=result;
C=Insertlist(L,C);
pl=pl->
ql=ql->
}
else{//相加后结果为0
elseif(pl->
ql->
j){//结点pl的列号小于结点ql的列号
L=(Lnode*)malloc(sizeof(Lnode));
L->
data=pl->
C=Insertlist(L,C);
pl=pl->
else{//结点pl的列号大于于结点ql的列号
i=ql->
j=ql->
data=ql->
ql=ql->
=NULL){//该行链表中A矩阵的结点未比较完
=NULL){//该行链表中B矩阵的结点未比较完
intPlus_condition(Crosslist*A,Crosslist*B){//两矩阵相加条件判断
if(A->
m==B->
m&
A->
n==B->
n)//同行同列
return1;
elseif(A->
m!
=B->
n)//同列不同行
return2;
n!
n)//同行不同列
return3;
n)//不同行也不同列
return4;
intmenu(){//选择菜单
intselect;
┏━━━━━━━━━━━┓\n"
┃┃\n"
┃重新输入矩阵0┃\n"
┃退出1┃\n"
┗━━━━━━━━━━━┛\n"
请选择:
"
select);
while(select<
0||select>
1){
输入错误,请重新选择:
returnselect;
voiddeal_mistake(Crosslist*A,Crosslist*B,Crosslist*C){//处理出现错误运算条件的情况
switch(menu()){
case0:
free(A);
free(B);
intcondition;
请输入矩阵A的"
A=Setcrosslist();
请输入矩阵B的"
B=Setcrosslist();
condition=Plus_condition(A,B);
//判断是否满足相加条件
if(condition==1){
C=Matrixplus(A,B);
矩阵A、B相加后:
Crosslistout(C);
//输出相加后的结果
elseif(condition==2){
矩阵A与矩阵B的行数不同,不满足矩阵相加条件!
deal_mistake(A,B,C);
//调用处理错误条件函数
elseif(condition==3){
矩阵A与矩阵B的列数不同,不满足矩阵相加条件!
deal_mistake(A,B,C);
elseif(condition==4){
矩阵A与矩阵B的行数、列数都不相同,不满足矩阵相加条件!
break;
case1:
exit(0);
voidmain(){
Crosslist*A,*B,*C;
intcondition;
C=Matrixplus(A,B);
elseif(condition==4){
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 课程设计报告 十字链表 课程设计 报告 十字