实验一参考.docx

上传人:b****6 文档编号:3298359 上传时间:2022-11-21 格式:DOCX 页数:29 大小:141.99KB
下载 相关 举报
实验一参考.docx_第1页
第1页 / 共29页
实验一参考.docx_第2页
第2页 / 共29页
实验一参考.docx_第3页
第3页 / 共29页
实验一参考.docx_第4页
第4页 / 共29页
实验一参考.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

实验一参考.docx

《实验一参考.docx》由会员分享,可在线阅读,更多相关《实验一参考.docx(29页珍藏版)》请在冰豆网上搜索。

实验一参考.docx

实验一参考

中南大学

 

《数据结构与算法》课程实验

实验报告

 

题目实验一线性表的操作

学生姓名

学生学号

专业班级

完成日期

1.需求分析

此实验要求我们掌握线性表的基本操作,插入、删除、查找,以及线性表合并等运算在顺序存储结构和链接存储结构上的运算。

顺序存储结构指的是用数组方法,链接存储结构指的是用链表方法,并通过对两种方法基本操作的掌握,实现一元n次多项式的加法运算。

输入的形式:

按照提示(比如:

“请输入第一个多项式”、“请输入多项式的项数”、“请输入第n项的系数”、“请输入第n项的指数”等等),先输入多项式的项数,之后顺次输入每一项的系数与指数。

输入值的范围:

项数没有要求,但不能过于巨大;系数取为float型数据,指数取为int型数据,

输出的形式:

按照提示(比如:

“输入的第二个多项式为”、“按降幂排列后多项式为”等等),会输出原输入的多项式和经过排序和合并之后的降幂型多项式。

同时,系数会以保留小数点后两位数字的形式输出;若指数输入时为小数,则输出时会自动截取其整数部分。

程序所能达到的功能:

程序可以对输入的序列紊乱的多项式进行加工,使之按照降幂排列,并合并指数相同的项,之后对两多项式进行加法运算(包括系数为负的加法),最后输出最终的多项式。

测试数据:

正确数据:

输入:

5*X^2+4*X^1和-3*X^2+2*X^0

输出:

2.00*X^2+4.00*X^1+2.00

错误数据:

输入:

-2*X^1.5+4*X^2和3*X^2+4*X^1.6

输出:

7.00*X^2+2.00*X^1

2.概要设计

(1)链接存储结构:

此方法中用到的抽象数据类型为结构体:

structnode

{

floatcoef;

intexpo;

structnode*next;

}link;

主程序中给提示建立第一个多项式,并依次调用create函数、order函数和hebing函数,通过调用print函数输出原多项式和整理过后的新多项式。

同理建立并输出第二个多项式,最后通过调用add函数,将两多项式相加,并调用order函数进行整理,最后调用print函数输出结果多项式。

(2)顺序存储结构

此方法中用到的抽象数据类型为结构体:

structpoly

{

floatcoef;

intexpo;

}dxs[15],dxs1[15],dxs2[30];

主函数中也会给出提示建立第一个多项式,并依次调用create函数和order函数,通过两次调用print函数输出原多项式和整理过后的新多项式。

之后,将多项式保存,然后同理建立第二个多项式,最后调用add函数,将两多项式相加。

调用print函数输出结果多项式。

因为此方法中我将合并函数加到order函数里,所以没有单一的hebing函数模块。

3.详细设计

(1)链接存储结构

此方法中定义了一个结构体类型:

structnode

{

floatcoef;//定义系数为float类型数据

intexpo;//定义指数为int类型数据

structnode*next;

}link;

structnode*create()//定义建立多项式函数,并返回链表头指针

{

structnode*h=NULL,*q,*p;//定义结构体头指针h,标记指针p和q

inti=1,N;//定义多项式的项数N及标记数i

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

{p=(structnode*)malloc(sizeof(link));//为下一个节点分配空间

scanf("%f",&p->coef);

scanf("%d",&p->expo);

if(i==1){h=p;q=p;}

else

{

q->next=p;

q=p;

}

}

q->next=NULL;

p->next=NULL;

returnh;

}

structnode*order(structnode*h)//定义排序函数,并返回整理后的链表的头指针

{

structnode*p,*q,*t,*h1,*h2;//定义三个结构体标记指针和两个头指针

h1=h;//建立一个新的链表,头指针为h,指向原链表的第一个节点,之后将原链表中的节点一个一个的插入此链表,进行排序

h2=h1->next;//将原来的链表建立成待排序链表

h1->next=NULL;//截断第一个原链表中的节点

while(h2!

=NULL)

{

q=h1;

p=q->next;

t=h2;//从待排序链表中选出一个节点准备插入到新链表中

h2=h2->next;//移动待排序链表的头指针,便于进行下一次挑选

t->next=NULL;

if(t->expo>q->expo)//应插入头指针之前的情况

{

t->next=q;

h1=t;

continue;

}

if(p==NULL&&t->expo<=q->expo)q->next=t;//应插入表尾的情况

while(p!

=NULL)

{

if(t->expo>p->expo)

{

q->next=t;

t->next=p;

break;

}

else

{

q=q->next;

p=p->next;

}

}

if(p==NULL)q->next=t;

}

returnh1;//新链表即为按降幂顺序排好的链表,返回其头指针

}

structnode*hebing(structnode*h)//定义合并函数,并返回合并后的链表的头指针

{

structnode*p,*q,*r;//定义三个结构体标记指针

p=h;

q=p->next;

while(q!

=NULL)

{

if(p->expo==q->expo)

{

p->coef=p->coef+q->coef;

r=q->next;

free(q);

p->next=r;

if(r!

=NULL)

{

q=r->next;

p=r;

}

}

else

{

p=p->next;

q=q->next;

}

}

returnh;

}

voidprint(structnode*h)//定义输出链表函数

{

structnode*p;//定义标记指针,输出链表

p=h;

while(p!

=NULL)

{

if(p->coef==0)p=p->next;//系数为零时跳过

else

{

if(p->coef<0)//系数为负时应加上括号

{

if(p->expo==0)printf("(%.2f)+",p->coef);

elseprintf("(%.2f)*X^%d+",p->coef,p->expo);

}

else

{

if(p->expo==0)printf("%.2f+",p->coef);

elseprintf("%.2f*X^%d+",p->coef,p->expo);

}

p=p->next;

}

}

printf("\b\b\n");

}

structnode*add(structnode*h1,structnode*h2)//定义加法函数,并返回结果的链表的头指针

{

structnode*p,*q,*head,*r;//定义结构体头指针head和标记指针p,q,r

p=h1;

q=h2;

head=(structnode*)malloc(sizeof(link));

if(p->expo>=q->expo){head=h1;p=p->next;}

else

{

if(p->expoexpo){head=h2;q=q->next;}

else{p->coef=p->coef+q->coef;head=p;p=p->next;q=q->next;}

}

r=head;

while(p!

=NULL&&q!

=NULL)

{

if(p->expo>q->expo){r->next=p;p=p->next;}

else

{

if(p->expoexpo){r->next=q;q=q->next;}

else{p->coef=p->coef+q->coef;r->next=p;p=p->next;q=q->next;}

}

r=r->next;

}

if(p==NULL&&q==NULL)r->next=NULL;

else

{

if(p==NULL)r->next=q;

if(q==NULL)r->next=p;

}

returnhead;

}

main()

{

structnode*h1,*h2,*h3;//定义三个结构体头指针标记多项式

h1=create();

h1=order(h1);

h1=hebing(h1);

print(h1);

h2=create();

h2=order(h2);

h2=hebing(h2);

print(h2);

h3=add(h1,h2);

h3=hebing(h3);

print(h3);

}

(2)顺序存储结构

此方法中也定义一个结构体类型:

structpoly

{

floatcoef;

intexpo;

}dxs[15],dxs1[15],dxs2[30];

voidcreate(intn)//定义建立结构体数组函数

{

inti;//定义数组中的循环标记数据i

for(i=0;i

{

scanf("%f",&dxs[i].coef);

scanf("%d",&dxs[i].expo);

}

}

voidprint(intn)//定义结构体数组输出函数

{

inti;//定义数组中的循环标记数据i

for(i=0;i

{

if(dxs[i].coef<0)

{

if(dxs[i].expo==0)printf("(%.2f)+",dxs[i].coef);

elseprintf("(%.2f)*X^%d+",dxs[i].coef,dxs[i].expo);

}

elseif(dxs[i].coef>0)

{

if(dxs[i].expo==0)printf("%.2f+",dxs[i].coef);

elseprintf("%.2f*X^%d+",dxs[i].coef,dxs[i].expo);

}

}

printf("\b\b\n");

}

voidorder(intn)//定义排序函数

{

inti,temp1,j;//定义数组中的循环标记数据i与j,和整型标记temp1

floattemp2;//定义单精度型标记temp2

for(i=0;i

for(j=i+1;j

{

if(dxs[j].expo>dxs[i].expo)

{

temp1=dxs[j].expo;

dxs[j].expo=dxs[i].expo;

dxs[i].expo=temp1;

temp2=dxs[j].coef;

dxs[j].coef=dxs[i].coef;

dxs[i].coef=temp2;

}

}

for(i=0;i

{

if(dxs[i].expo==dxs[i+1].expo)

{

dxs[i+1].coef=dxs[i].coef+dxs[i+1].coef;

if(i==n-2)

{

dxs[i].coef=dxs[i+1].coef;

dxs[i+1].coef=0;

}

else

{

for(j=i;j

{

dxs[j].coef=dxs[j+1].coef;

dxs[j].expo=dxs[j+1].expo;

}

dxs[j].coef=0;

i--;

}

}

}

}

voidadd(intn1,intn2)//定义加法函数

{

inti=0,j=0,p,m;//定义数组中的循环标记数据i,j,p,m

for(p=0;;p++)

{

if(dxs[i].expo==dxs1[j].expo)

{

dxs2[p].coef=dxs[i].coef+dxs1[j].coef;

dxs2[p].expo=dxs[i].expo;

i++;

j++;

}

else

{

if(dxs[i].expo>dxs1[j].expo)

{

dxs2[p].coef=dxs[i].coef;

dxs2[p].expo=dxs[i].expo;

i++;

}

else

{

dxs2[p].coef=dxs1[j].coef;

dxs2[p].expo=dxs1[j].expo;

j++;

}

}

if(i==n1||j==n2)

{

p++;

break;

}

}

if(i==n1)

for(;j

{

dxs2[p].coef=dxs1[j].coef;

dxs2[p].expo=dxs1[j].expo;

p++;

}

else

for(;i

{

dxs2[p].coef=dxs[i].coef;

dxs2[p].expo=dxs[i].expo;

p++;

}

for(m=0;m

{

if(dxs2[m].coef<0)

{

if(dxs2[m].expo==0)printf("(%.2f)+",dxs2[m].coef);

elseprintf("(%.2f)*X^%d+",dxs2[m].coef,dxs2[m].expo);

}

elseif(dxs2[m].coef>0)

{

if(dxs2[m].expo==0)printf("%.2f+",dxs2[m].coef);

elseprintf("%.2f*X^%d+",dxs2[m].coef,dxs2[m].expo);

}

}

printf("\b\b\n");

}

main()

{

intn1,n2,i;//定义多项式的项数n1与n2,和循环标记数据i

scanf("%d",&n1);

create(n1);

order(n1);

print(n1);

for(i=0;i

dxs1[i].coef=dxs[i].coef;

dxs1[i].expo=dxs[i].expo;

}

scanf("%d",&n2);

create(n2);

order(n2);

print(n2);

add(n1,n2);

}

4.调试分析

(1)链接存储结构

在此方法的实现过程中,没有比较大的麻烦,因为最近一直在用链表进行编程,已经比较熟悉了链表的基本操作,只是在一些实现方便与否、接近真实情况与否进行了一番思考。

首先,我因为做题的习惯,所以没有考虑到假如输入多项式时可以打乱顺序输入,即不按照降幂或升幂的形式进行输入。

意识到可能有此情况后,我就添加了一个order函数,对输入的原多项式进行排序,解决掉因打乱顺序输入而导致程序出错的可能性。

之后,又有人提出,假如多项式中有指数相同的项,那如果没有合并一类作用的函数做整理的话,也会出错。

因此,我又着手编一个合并函数。

合并函数其实不难,只要把原多项式进行排序后就变得很简单了。

只需要将指数相同的项的系数进行加法运算,之后删去后一个节点即可。

最后,还有一个输出形式的问题。

因为假如系数是负数的时候,需要将其用括号括起来,这也是数学运算中的规定。

因此,我又对输出函数:

print函数进行了一些修改,并且在修改过程中又发现,假如指数为零时,输出的应该是只有系数,所以我又顺便将这方面的漏洞加以补充。

当然,我这个程序毕竟还是有不足之处的。

一、没有利用到链表的一项基本操作:

删除节点。

在输出过程中,我对系数为零的节点的处理方式是跳过,而不是删除,虽然不会影响到最终的输出结果,但对内存其实是有一些浪费,毕竟程序需要的不仅是结果正确,而且还要做到时间和空间上的节约。

二、当一项的指数为1时,应当输出的是X,而不是X^1,所以此方面仍需要改进。

虽然此项改进不是很难,但由于时间紧迫,没有来得及修改,但我会在以后的空闲时间内将其完善。

在算法的时空复杂度上,我没有进行过多的考虑,因为现在自己的水平还没有那么高,我只知道,在排序函数中,我用的冒泡排序方法是一种效率很低的方法,时间复杂度为O(n2)。

而同学向我推荐过的一种插入排序方法,一种部分有序的排序方法,算下来时间复杂度为O(n2-n),因此自己还需要将此程序加以改进。

(2)顺序存储结构

在此方法的实现过程中,我确实费了很大的时间。

因为数组很长时间没有用到过了,很多基本操作又比链表复杂,因此,我花了相当长的时间才将此程序完成。

定义结构体数组方面虽然很简单,但用起来就会变的相当复杂,并且由于自己的数组方面的知识不是很牢靠,因此,语法错误很多,调试费了很长的时间,并且很多次无法通过编译。

最终在同学的帮助下,自己又花了大量的时间,终于将程序编出。

因为程序需要的作用函数已在链表方法中掌握,所以此项内容里我没有进行更多的考虑,只是感觉用结构体数组实现的时候,将排序函数和合并函数写在一起会更加方便,所以此方法中我只设置了一个排序函数,并且在做加法的函数中附带了输出作用,因此不再调用print函数输出数组。

但此相加的函数似乎有点问题,在多项式比较复杂的时候,输出总是有点问题。

自己研究了很长时间之后还是找不出问题,希望老师能发现并指出,完善此程序。

通过编此程序,我感觉到自己在数组的知识点上掌握的不够扎实,以后还需多加练习,熟练掌握数组的基本操作方法。

5.用户使用说明

(1)链接存储结构

运行程序后,会出现提示:

请输入第一个多项式

请输入多项式的项数:

(这时应输入其项数(整型数据),后按回车键;比如输入:

2)

请输入第1项的系数:

请输入第1项的指数:

(比如依次输入2,2)

请输入第2项的系数:

请输入第2项的指数:

(比如依次输入3,3)

输入的第一个多项式为:

2.00*X^2+3.00*X^3

按降幂排列后多项式为:

3.00*X^3+2.00*X^2

请输入第二个多项式;

请输入多项式的项数:

(比如输入:

2)

请输入第1项的系数:

请输入第1项的指数:

(比如依次输入1,1)

请输入第2项的系数:

请输入第2项的指数:

(比如依次输入2,2)

输入的第一个多项式为:

1.00*X^1+2.00*X^2

按降幂排列后多项式为:

2.00*X^2+1.00*X^1

相加后的多项式为:

3.00*X^3+4.00*X^2+1.00*X^1

(2)顺序存储结构

请输入第一个多项式的项数:

(比如输入:

2)

请输入第1项的系数:

请输入第1项的指数:

(比如依次输入2,2)

请输入第2项的系数:

请输入第2项的指数:

(比如依次输入3,3)

您输入的第一个多项式为:

2.00*X^2+3.00*X^3

降幂排序后该多项式变为:

3.00*X^3+2.00*X^2

请输入第二个多项式的项数:

(比如输入:

2)

请输入第1项的系数:

请输入第1项的指数:

(比如依次输入1,1)

请输入第2项的系数:

请输入第2项的指数:

(比如依次输入2,2)

您输入的第一个多项式为:

1.00*X^1+2.00*X^2

降幂排序后该多项式变为:

2.00*X^2+1.00*X^1

两个多项式相加后的结果为:

3.00*X^3+4.00*X^2+1.00*X^1

6.测试结果

(1)链接存储结构

(2)顺序存储结构

7.附录

(1)链接存储结构

#include"stdio.h"

#include"stdlib.h"

structnode

{

floatcoef;//定义系数为float类型数据

intexpo;//定义指数为int类型数据

structnode*next;

}link;

structnode*create()//定义建立多项式函数,并返回链表头指针

{

structnode*h=NULL,*q,*p;//定义结构体头指针h,标记指针p和q

inti=1,N;//定义多项式的项数N及标记数i

printf("请输入多项式的项数:

");

scanf("%d",&N);

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

{p=(structnode*)malloc(sizeof(link));//为下一个节点分配空间

printf("请输入第%d项的系数:

",i);

scanf("%f",&p->coef);

fflush(stdin);

printf("请输入第%d项的指数:

",i);

scanf("%d",&p->expo);

fflush(stdin);

if(i==1){h=p;q=p;}//建立头节点

else

{

q->next=p;

q=p;

}

}

q->next=NULL;

p->next=NULL;

returnh;

}

structnode*order(structnode*h)//定义排序函数,并返回整理后的链表的头指针

{

structnode*p,*q,*t,*h1,*h2;//定义三个结构体标记指针和两个头指针

h1=h;//建立一个新的链表,头指针为h,指向原链表的第一个节点,之后将原链表中的节点一个一个的插入此链表,进行排序

h2=h1->next;//将原来的链表建立成待排序链表

h1->next=NULL;//截断第一个原链表中的节点

while(h2!

=NULL)

{

q=h1;

p=q->next;

t=h2;//从待排序链表中选出一个节点准备插入到新链表中

h2=h2->next;//移动待排序链表的头指针,便于进行下一次挑选

t->next=NULL;

if(t->expo>q->expo)//应插入头指针之前的情况

{

t->next=q;

h1=t;

continue;

}

if(p==NULL&&t->expo<=q->expo)q->next=t;//应插入表尾的情况

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

当前位置:首页 > 小学教育 > 语文

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

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