云南大学数据结构实验2.docx
- 文档编号:6282971
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:19
- 大小:71.36KB
云南大学数据结构实验2.docx
《云南大学数据结构实验2.docx》由会员分享,可在线阅读,更多相关《云南大学数据结构实验2.docx(19页珍藏版)》请在冰豆网上搜索。
云南大学数据结构实验2
实验难度:
A□BC□
序号
学号
姓名
成绩
指导教师
(签名)
学 期:
2017秋季学期
**** **
实验题目:
线性表及其应用
组员及组长:
承担工作:
联系电话:
电子邮件:
完成提交时间:
2018年11月2日
一、【实验构思(Conceive)】(10%)
(本部分应包括:
描述实验实现的基本思路,包括所用到的离散数学、工程数学、程序设计等相关知识,对问题进行概要性地分析)
本实验通过C语言利用链表实现了多项式加法、减法、乘法、多项式求导、多项式积分的功能。
利用了插入排序的算法作为排序的核心算法。
运用了高等数学中多项式的求导积分的知识。
二、【实验设计(Design)】(20%)
(本部分应包括:
抽象数据类型的定义和基本操作说明,程序包含的模块以及各模块间的调用关系,关键算法伪码描述及程序流程图等,如有界面则需包括界面设计,功能说明等)
抽象数据类型的定义:
typedefstructNode{
floatxishu;//定义系数为浮点数
intzhishu;//定义指数为整型
structNode*Next;
}Node;
基本操作:
可对多项式进行排序输出,实现多项式的求导与加减运算
模块:
多项式排序:
voidinsertNewPoint_link(PNodehead,PNodeqNode)
voidinsertNewPoint_link(PNodehead,PNodeqNode)
{
while(项数不为1)
{
if(新项大于某一旧项指数){
插在前面;
退出;
}
elseif(等于某一旧项的指数){
计算合并后的系数;
if(s系数不为0)
附给新项;
else{
删去已有的项;
销毁结点;
}
退出;
}
指向下一个;
}
if(只有一项)
不排序退出;
}
多项式输出:
voidprintLinkeLink(PNodehead)
多项式求导:
voidder_poly(Node*pa)
voidder_poly(Node*pa)
{
指向头指针;
while(多项式不为空)
{
floatx=多项式指数乘以多项式系数;
floaty=多项式指数减1;
x附给指数;
y附给系数;
指针指向下一个;
}
}
多项式加法:
voidadd_poly(Node*pa,Node*pb)
voidadd_poly(Node*pa,Node*pb)
{
指针指向多项式A、B的第一项;
while(项都不为空)
{
if(A项系数大于B项)
{
指针指向下一个;
}
elseif(相同)
{
合并系数
if(系数不为0)
{
系数赋给多项式一中对应的项;
}
else
{
指向下一个结点;
释放销毁结点;
}
指针都指向下一个;
销毁B的这一项;
}
else
{
插入B的项;
}
}
}
多项式减法:
voidsub_poly(Node*pa,Node*pb)
同上
本程序所有模块皆只在主程序中调用
主程序流程图:
三、【实现(Implement)】(30%)
(本部分应包括:
抽象数据类型各操作的具体实现代码、关键操作的具体算法实现、函数实现,主程序实现等,并给出关键算法的时间复杂度分析。
如有界面则需包括界面的关键实现方法等。
)
多项式按照指数大小排序:
voidinsertNewPoint_link(PNodehead,PNodeqNode)
{
PNodep=head;//向head为首的链表中插入qnode结点,由p从head处开始遍历
PNodeh=head;
PNodeq;//用于销毁节点
while(p->Next!
=NULL)//若已输入多项式不止一项
{
//若新项的指数比某一项p大则将新项插在该项前面
if(p->Next->zhishu
qNode->Next=p->Next;
p->Next=qNode;
break;//插完之后即可退出
}
elseif(p->Next->zhishu==qNode->zhishu)
{
floatsum=p->Next->xishu+qNode->xishu;//计算合并后的系数
if(sum!
=0)//若合并后系数不为零
p->Next->xishu=sum;//重新赋予p项新的系数
else//否则删去已有链表中的第一项
{
q=p->Next;
p->Next=p->Next->Next;
free(q);//销毁结点
q=NULL;
}
break;
}
p=p->Next;//若新项指数小于p当前指向的项则p移至下一项与下一项进行比较
}
if(p->Next==NULL)//若多项式只有一项则无需排序
p->Next=qNode;
}
多项式求导:
voidder_poly(Node*pa)
{
Node*p=pa->Next;
Node*pre=pa;//pre此刻指向多项式一的头指针,后续作为中间载体
while(p!
=NULL)
{
floatx=p->xishu*p->zhishu;
floaty=p->zhishu-1;
p->xishu=x;
p->zhishu=y;
pre=p;//pre指向p结点
p=pre->Next;
}
}
多项式加法:
voidadd_poly(Node*pa,Node*pb)
{
Node*p=pa->Next;
Node*q=pb->Next;
Node*pre=pa;//pre此刻指向多项式一的头指针,后续作为中间载体
Node*u;//u指针做临时指针,用于释放节点
while(p!
=NULL&&q!
=NULL)//若指针指向的内容都不为空
{
if(p->zhishu>q->zhishu)//若多项式一中的项系数大于对应多项式二中的项
{
pre=p;
p=p->Next;
}
elseif(p->zhishu==q->zhishu)//若两项系数相等则合并同类项
{
floatx=p->xishu+q->xishu;//x为合并后的系数
if(x!
=0)//若合并后系数不为零
{
p->xishu=x;//将合并后的系数赋给多项式一中对应的项
pre=p;//pre指向p结点
}
else//若合并后系数为零
{
pre->Next=p->Next;//指向下一个结点
free(p);//释放p销毁结点
}
p=pre->Next;
u=q;
q=q->Next;
free(u);
}
else//若多项式一中的项系数小于对应多项式二中的项
{
u=q->Next;
q->Next=p;
pre->Next=q;
pre=q;
q=u;
}
}
if(q)
pre->Next=q;
free(pb);
}
若n为最长多项式长度
则算法复杂度皆为O(n)
四、【测试结果(Testing)】(10%)
(本部分应包括:
对实验的测试结果,应具体列出每次测试所输入的数据以及输出的数据,并对测试结果进行分析,可附截图)
求导:
加法:
减法:
五、【实验总结】(10%)
(本部分应包括:
自己在实验中完成的任务,及存在的问题,所完成实验过程中的具体经验总结、心得)
这是第一次用双链表编写多项式运算器,感到使用抽象数的类型的线性表的方便之处,以后还会多多使用的,同时整个程序运行期间实行动态存储管理,释放了无用空间。
在执行一元多项式加减法的时候,把指针P->next域搞乱,容易造成死循环。
创建一元多项式链表时,可能不是按照指数域的大小输入,故增加了排序,按指数域,对链表进行排序
六、思考题(10%)
(注:
选择C难度的才需要填写“项目运作描述”,其他难度的只需完成思考题)
(项目运作描述应包括:
项目的成本效益分析,应用效果等的分析。
)
顺序存储结构用一段连续的存储单元依次存储线性表的数据元素,需要预分配存储空间,分大了,容易造成空间浪费,分小了,容易发生溢出;单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素,不需要分配存储空间,只要有就可以分配,元素个数也不受限制。
在通常的应用中,多项式的次数可能很高且变化很大,使得顺序存储结构的最大长度很难确定。
由稀疏多项式的特点,故采用链式存储结构,可以不会带来浪费存储空间。
程序中单链表存储,根据链表的指数域,对链表进行排序,可给运算带来方便。
七、【代码】(10%)
(本部分应包括:
完整的代码及充分的注释。
注意纸质的实验报告无需包括此部分。
格式统一为,字体:
Georgia,行距:
固定行距12,字号:
小五)
#include
#include
typedefstructNode{
floatxishu;//定义系数为浮点数
intzhishu;//定义指数为整型
structNode*Next;
}Node;
typedefstructNode*PNode;//定义指针类型
//多项式按照指数大小排序
voidinsertNewPoint_link(PNodehead,PNodeqNode)
{
PNodep=head;//向head为首的链表中插入qnode结点,由p从head处开始遍历
PNodeh=head;
PNodeq;//用于销毁节点
while(p->Next!
=NULL)//若已输入多项式不止一项
{
//若新项的指数比某一项p大则将新项插在该项前面
if(p->Next->zhishu
qNode->Next=p->Next;
p->Next=qNode;
break;//插完之后即可退出
}
elseif(p->Next->zhishu==qNode->zhishu)
{
floatsum=p->Next->xishu+qNode->xishu;//计算合并后的系数
if(sum!
=0)//若合并后系数不为零
p->Next->xishu=sum;//重新赋予p项新的系数
else//否则删去已有链表中的第一项
{
q=p->Next;
p->Next=p->Next->Next;
free(q);//销毁结点
q=NULL;
}
break;
}
p=p->Next;//若新项指数小于p当前指向的项则p移至下一项与下一项进行比较
}
if(p->Next==NULL)//若多项式只有一项则无需排序
p->Next=qNode;
}
//输出多项式
voidprintLinkeLink(PNodehead)
{
PNodetemp=head->Next;
printf("%fX^%d",temp->xishu,temp->zhishu);
temp=temp->Next;
while(temp!
=NULL)
{
if(temp->xishu>0)//若为正系数
printf("+%fX^%d",temp->xishu,temp->zhishu);
elseif(temp->xishu<0)//若为负系数
printf("%fX^%d",temp->xishu,temp->zhishu);
temp=temp->Next;
}
}
//多项式的求导计算
voidder_poly(Node*pa)
{
Node*p=pa->Next;
Node*pre=pa;//pre此刻指向多项式一的头指针,后续作为中间载体
while(p!
=NULL)
{
floatx=p->xishu*p->zhishu;
floaty=p->zhishu-1;
p->xishu=x;
p->zhishu=y;
pre=p;//pre指向p结点
p=pre->Next;
}
}
//多项式的加法计算
voidadd_poly(Node*pa,Node*pb)
{
Node*p=pa->Next;
Node*q=pb->Next;
Node*pre=pa;//pre此刻指向多项式一的头指针,后续作为中间载体
Node*u;//u指针做临时指针,用于释放节点
while(p!
=NULL&&q!
=NULL)//若指针指向的内容都不为空
{
if(p->zhishu>q->zhishu)//若多项式一中的项系数大于对应多项式二中的项
{
pre=p;
p=p->Next;
}
elseif(p->zhishu==q->zhishu)//若两项系数相等则合并同类项
{
floatx=p->xishu+q->xishu;//x为合并后的系数
if(x!
=0)//若合并后系数不为零
{
p->xishu=x;//将合并后的系数赋给多项式一中对应的项
pre=p;//pre指向p结点
}
else//若合并后系数为零
{
pre->Next=p->Next;//指向下一个结点
free(p);//释放p销毁结点
}
p=pre->Next;
u=q;
q=q->Next;
free(u);
}
else//若多项式一中的项系数小于对应多项式二中的项
{
u=q->Next;
q->Next=p;
pre->Next=q;
pre=q;
q=u;
}
}
if(q)
pre->Next=q;
free(pb);
}
//多项式的减法计算
voidsub_poly(Node*pa,Node*pb)
{
Node*p=pa->Next;
Node*q=pb->Next;
Node*pre=pa;//pre此刻指向多项式一的头指针,后续作为中间载体
Node*u;//u指针做临时指针,用于释放节点
while(p!
=NULL&&q!
=NULL)//若指针指向的内容都不为空
{
if(p->zhishu>q->zhishu)//若多项式一中的项系数大于对应多项式二中的项
{
pre=p;
p=p->Next;
}
elseif(p->zhishu==q->zhishu)//若两项系数相等则合并同类项
{
floatx=p->xishu-q->xishu;//x为合并后的系数
if(x!
=0)//若合并后系数不为零
{
p->xishu=x;//将合并后的系数赋给多项式一中对应的项
pre=p;//pre指向p结点
}
else//若合并后系数为零
{
pre->Next=p->Next;//指向下一个结点
free(p);//释放p销毁结点
}
p=pre->Next;
u=q;
q=q->Next;
free(u);
}
else//若多项式一中的项系数小于对应多项式二中的项
{
u=q->Next;
q->Next=p;
pre->Next=q;
pre=q;
q=u;
}
}
if(q)
pre->Next=q;
free(pb);
}
//实现主函数
voidmain()
{
floatxishu;//定义变量系数和指数
intzhishu;
PNodehead1=(PNode)malloc(sizeof(structNode));
PNodetem=NULL;
head1->Next=NULL;
charch='!
';
printf("是否是要进行求导运算(Y/N):
");
while(ch=='!
')
{
scanf("\n%c",&ch);
if(ch!
='Y'&&ch!
='N'&&ch!
='y'&&ch!
='n'){
printf("错误!
请重新输入:
");
ch='!
';
}
}
//输入多项式一各项
printf("输入链表一的系数和指数,如:
3,2(以0,0结束输入):
\n");
scanf("%f,%d",&xishu,&zhishu);
while(xishu!
=0)//当系数为零时停止输入
{
tem=(PNode)malloc(sizeof(structNode));//往链表中插入新的项
tem->xishu=xishu;
tem->zhishu=zhishu;
tem->Next=NULL;
insertNewPoint_link(head1,tem);//插入新结点
scanf("%f,%d",&xishu,&zhishu);//输入下一项
}
printf("多项式一为:
\n");
printLinkeLink(head1);//输出多项式一
printf("\n");
if(ch=='Y'||ch=='y'){
der_poly(head1);
printf("\n多项式求导后的结果为:
\n");
}
else{
PNodehead2=(PNode)malloc(sizeof(structNode));
head2->Next=NULL;
//输入多项式二各项
printf("\n输入链表二的系数和指数,如:
3,2(以0,0结束输入):
\n");
scanf("%f,%d",&xishu,&zhishu);
while(xishu!
=0)//当系数为零时停止输入
{
tem=(PNode)malloc(sizeof(structNode));
tem->xishu=xishu;
tem->zhishu=zhishu;
tem->Next=NULL;
insertNewPoint_link(head2,tem);
scanf("%f,%d",&xishu,&zhishu);
}
printf("多项式二为:
\n");
printLinkeLink(head2);
printf("\n");
ch='!
';
printf("\n输入你想要的操作(+-):
");
while(ch=='!
')
{
scanf("\n%c",&ch);
if(ch=='+'){
sub_poly(head1,head2);
printf("\n多项式相加后的结果为:
\n");
}
elseif(ch=='-'){
sub_poly(head1,head2);
printf("\n多项式相减后的结果为:
\n");
}
else{
printf("错误!
请重新输入:
");
ch='!
';
}
}
}
printf("\n");
//输出多项式的结果
printLinkeLink(head1);
printf("\n\n");
system("pause");
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 云南大学 数据结构 实验