实验二 链表 实验报告.docx
- 文档编号:4690659
- 上传时间:2022-12-07
- 格式:DOCX
- 页数:21
- 大小:419.14KB
实验二 链表 实验报告.docx
《实验二 链表 实验报告.docx》由会员分享,可在线阅读,更多相关《实验二 链表 实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
实验二链表实验报告
一元多项式表达和相加实验报告
一、实验内容和目的
实验目的:
掌握单链表的建立、合并和遍历操作
实验内容:
1.单链表的建立(创建一个一元多项式)
2.单链表的遍历(一元多项式的输出、一元多项式的项数统计)
3.单链表的合并(一元多项式的加减运算)
二、实验原理
基本原理:
使用单链表储存一元多项式的指数和系数信息。
每个结点含有两个数据域,分别用于存放每一项的指数和系数;一个指针域用于存放下一个结点的指针。
一个完整的链表表示一个一元多项式。
单链表的建立:
为了后续操作的方便,本实验中创建的单链表是按指数倒序排序的。
例:
创建一元多项式:
为了更好说明建立的过程,输入的过程并非按照指数降序的顺序输入。
实际的输入如下:
步骤一:
把最先输入的数据作为链表的第一个结点
步骤二:
用第二个数据创建一个新的结点,如果新结点指数大于某个结点,则新的结点插在该结点的前面;否则跟后面一个再比较(源码中p和q指针向链表后移动);如果新的结点比前面的每一个结点都要小(即q指向链表最后一个结点),则插在链表的末尾端。
下图为新结点中指数比前面每个结点的指数都要小
如果发现新结点的指数大于链表中某个特定结点时(图中红色数字表示操作顺序)
不断重复上述步骤,直到所有的数据都储存到单链表中。
单链表的合并(即本例中的一元多项式的加减法):
根据上述的链表创建算法,创建好的链表都具有按指数大小降序的特点。
为了确保合并以后的单链表也具有此特点,因此合并的过程中,同样会边合并,边比较大小,从而确保合并的结果仍然具有此特性。
例:
多项式P1为:
多项式P2为:
多项式运算P1+P2的结果为:
从上述的链表创建算法可以创建出两个对应的链表
先利用两个指针,Pa和Pb,分别指向两个多项式的结点。
如果Pa指向结点指数大于Pb指向结点的指数,把Pa指向的结点插入到新的链表之中。
具体步骤如图
如果Pa指向结点指数小于Pb指向结点的指数,则把Pb指向的结点插入到新的链表之中。
具体步骤如图
如果Pa指向的结点指数等于Pb指向的结点指数,则先把两者指向结点指数相加,储存到Pa指向结点中。
移动Pa,Pb指针,释放原来Pb指向的结点。
具体步骤如图
一直重复上述操作,当其中一个链表结点已经全部插入到新的链表中时,则把另外一个链表剩下的所有结点插入到链表之中(即只需要把剩下的结点接起来)。
具体步骤
如图
当完成上述的操作,把Pa指针指向新链表的指向新的链表头。
把旧的两个链表头释放掉。
一元多项式的减法,实际上也是一元多项式的加法。
程序对于一元多项式的减法处理如下,A和B是两个多项式,A-B=A+(-B),也就是说,把作为减数的多项式中每一项的系数变成其相反数,然后将两个多项式进行加法运算。
三、
程序流程图
四、实验结果
4.1程序主菜单
4.2创建多项式
4.3一元多项式的加法操作
4.4一元多项式的减法操作
4.5求一元多项式系数操作
五、操作说明
1.主菜单中的1(创建一元多项式)2(输出一元多项式)5(求一元多项式操作)三个选项操作的对象是同一个一元多项式,因此,要使用输出和求项数功能之前,需要选择1(创建一元多项式)创建多项式。
2.多项式的加减操作的操作对象是两个新的多项式,操作结束以后,进行加减运算的多项式和结果多项式均不会保存。
3.在多项式的加减运算过程中,只要其中一个多项式的创建出现问题,整个加减法运算操作就会终止。
六、附录:
代码
#include
#include
#defineOK0
#defineERROR1
typedefstructLNode
{
intexp;//指数
floatcoef;//系数
structLNode*next;//指针域
}LNode;
/*基本操作的实现*/
//向链表中插入一个新的结点(插入过程中保持指数降序排序)
//hNode头结点
//nNode要插入的新结点
intInsertLNode(LNode*hNode,LNode*nNode)
{
LNode*p,*q;
//如果链表为空表,则把元素放在链表第一个位置
if(hNode->next==NULL)
{
hNode->next=nNode;
}
else
{
p=hNode;
q=hNode->next;
while(q!
=NULL)
{
//如果新的结点指数比q结点的指数大,则该结点插在q结点的前面
if(nNode->exp>q->exp)
{
nNode->next=q;
p->next=nNode;
break;
}
//如果新的结点指数与q的指数相等,指数相加,不插入结点
if(nNode->exp==q->exp)
{
q->coef=nNode->coef+q->coef;
free(nNode);
break;
}
//如果新的结点指数比q的指数小
//如果q是最后一个结点,直接插入在q的后面
//如果q不是最后一个结点,则q指针往后移动
if(q->next==NULL)
{
nNode->next=q->next;
q->next=nNode;
break;
}
else
{
p=p->next;
q=q->next;
}
}
}
returnOK;
}
//两个多项式的相加操作
//因为相加过程中,会根据指数的大小,一边运算一般排序
//因此,要求传入的Pa和Pb都是按指数降序排序的一元多项式
voidAddPolyn(LNode*Pa,LNode*Pb)
{
LNode*head,*q,*tmp;//用于储存新创建的多项式
LNode*recycle;//用于指数相等系数相加后结点的释放
LNode*PtrB;//用于合并完成后链表头结点的释放
head=(LNode*)malloc(sizeof(LNode*));
head->next=NULL;
q=head;
PtrB=Pb;
Pa=Pa->next;
Pb=Pb->next;
//如果Pa和Pb指针不同时为空
while(Pa&&Pb)
{
//如果Pa所指向结点的指数大于Pb所指向结点的指数
if(Pa->exp>Pb->exp)
{
//把Pa指向的结点插入到新的链表之中
tmp=Pa;
Pa=Pa->next;
tmp->next=NULL;
q->next=tmp;
q=q->next;
continue;
}
//如果Pa所指向结点的指数等于Pb所指向结点的指数
if(Pa->exp==Pb->exp)
{
//先把Pa指向结点和Pb指向结点的系数相加,并储存到Pa指向的结点
//再把Pa指向的结点插入到新的链表之中
tmp=Pa;
tmp->coef=tmp->coef+Pb->coef;
recycle=Pb;
Pa=Pa->next;
Pb=Pb->next;
free(recycle);
tmp->next=NULL;
q->next=tmp;
q=q->next;
continue;
}
//如果Pa所指向结点的指数小于Pb所指向结点的指数
if(Pa->exp
{
//把Pb指向的结点插入到新的链表
tmp=Pb;
Pb=Pb->next;
tmp->next=NULL;
q->next=tmp;
q=q->next;
continue;
}
}
//如果其中一个链表已经遍历完毕,把链表剩下的所有结点插入到新的链表之中
if(Pa)
{
q->next=Pa;
}
if(Pb)
{
q->next=Pb;
}
PtrB->next=NULL;
//释放旧的链表头结点
free(PtrB);
//把新的链表头结点赋到Pa
Pa=head;
}
//对两个一元多项式进行相减操作
//A-B=A+(-B)
voidSubtractPolyn(LNode*Pa,LNode*Pb)
{
LNode*p;
//把Lb中每项的系数变成其相反数
for(p=Pb->next;p!
=NULL;p=p->next)
p->coef=-(p->coef);
AddPolyn(Pa,Pb);
}
/*具体功能的实现*/
intCreatePolynomial(LNode*hNode)
{
inti,n,exp;
floatcoef;
LNode*node;
printf("请输入多项式的项数:
");
//如果输入的不是整数
if(scanf("%d",&n)==0)
{
printf("无效输入...\n");
returnERROR;
}
//清空上述操作中未读入的数值。
防止对后面的操作产生影响
fflush(stdin);
printf("即将创建一个项数为%d的多项式\n",n);
printf("输入的格式为:
先系数后指数,两者之间使用英文逗号间隔\n");
for(i=1;i<=n;i++)
{
printf("请输入第%d项的系数和指数:
",i);
//防止不正确输入导致的死循环
fflush(stdin);
//操作前检查输入的有效性
//如果输入的数据无效则要求重新输入
if(scanf("%f,%d",&coef,&exp)==2)
{
node=(LNode*)malloc(sizeof(LNode));
if(!
node)
{
printf("内存分配失败!
\n");
system("pause");
returnERROR;
}
//向新结点赋值
node->exp=exp;
node->coef=coef;
node->next=NULL;
//把新结点插入到链表之中
InsertLNode(hNode,node);
}
else
{
printf("输入无效,请重新输入。
\n");
i--;
}
}
if(i==n+1)
returnOK;
else
returnERROR;
}
voidPrintPolynomial(LNode*head)
{
LNode*p=head->next;
inti=0;//用于控制加号输出
while(p!
=NULL)
{
//如果系数不为0,输出该项
if(p->coef!
=0)
{
//根据参数的正负输出加减号
if(i++!
=0&&p->coef>0)
putchar('+');
printf("%.2fx^%d",p->coef,p->exp);
//防止系数为0的前一项的指数被覆盖
if(p->next&&p->next->coef==0)
printf("");
}
else
printf("\b");//覆盖前面的加号
p=p->next;
}
printf("\n");
}
//遍历并输出整数序列
voidListTravel(LNode*head)
{
intn=0;
LNode*p;
//先对多项式的项数进行统计
for(p=head->next;p!
=NULL;p=p->next)
n++;
//输出项数
printf("%d,",n);
//通过链表的遍历实现整数序列中的指数和系数部分
for(p=head->next;p!
=NULL;p=p->next)
printf("%.2f,%d,",p->coef,p->exp);
}
voidListCount(LNode*head)
{
LNode*p;
inti=0;
//每发现一个非空结点,i加一
for(p=head->next;p!
=NULL;p=p->next)
i++;
printf("\n该一元多项式有%d项\n\n",i);
system("pause");
}
//创建两个一元多项式并相加
voidCreateAndPlus()
{
LNode*La,*Lb;
//为两个新的链表分配内存空间
La=(LNode*)malloc(sizeof(LNode));
Lb=(LNode*)malloc(sizeof(LNode));
La->next=NULL;
Lb->next=NULL;
//清屏
system("cls");
printf("\n现在创建第一个一元多项式\n\n");
if(CreatePolynomial(La)==ERROR)
{
printf("创建多项式时出现错误,即将返回主菜单...\n");
system("pause");
return;
}
PrintPolynomial(La);
printf("\n现在创建第二个一元多项式\n\n");
if(CreatePolynomial(Lb)==ERROR)
{
printf("创建多项式时出现错误,即将返回主菜单...\n");
system("pause");
return;
}
PrintPolynomial(Lb);
printf("\n求和结果:
\n");
AddPolyn(La,Lb);
PrintPolynomial(La);
system("pause");
}
voidCreateAndSubtract()
{
LNode*La,*Lb;
//为两个新的链表分配内存空间
La=(LNode*)malloc(sizeof(LNode));
Lb=(LNode*)malloc(sizeof(LNode));
La->next=NULL;
Lb->next=NULL;
//清屏
system("cls");
printf("\n现在创建第一个一元多项式\n\n");
if(CreatePolynomial(La)==ERROR)
{
printf("创建多项式时出现错误,即将返回主菜单...\n");
system("pause");
return;
}
PrintPolynomial(La);
printf("\n现在创建第二个一元多项式\n\n");
if(CreatePolynomial(Lb)==ERROR)
{
printf("创建多项式时出现错误,即将返回主菜单...\n");
system("pause");
return;
}
PrintPolynomial(Lb);
printf("\n两个多项式相减以后的结果:
\n");
SubtractPolyn(La,Lb);
PrintPolynomial(La);
system("pause");
}
intmain(void)
{
LNode*head=(LNode*)malloc(sizeof(LNode));
charch='\0';
if(!
head)
{
printf("链表头指针内存分配失败!
\n");
system("pause");
returnERROR;
}
head->next=NULL;
while
(1)
{
//解决闪屏或者不能接受用户输入的问题
fflush(stdin);
system("cls");
printf("\n\n");
printf("单链表的应用演示程序\n");
printf("一元多项式的表示及相加\n");
printf("\n");
printf("1.创建一个一元多项式并输出\n");
printf("2.遍历单链表并输出整数序列\n");
printf("3.创建两个一元多项式并相加\n");
printf("4.创建两个一元多项式并相减\n");
printf("5.求一个一元多项式中的项数\n");
printf("\n");
printf("Q.退出程序\n");
printf("\n\n");
printf("请选择:
");
scanf("%c",&ch);
switch(ch)
{
case'1':
system("cls");
//如果链表已经创建,则需要重新分配空间
//并释放原有的空间
if(head->next!
=NULL)
{
free(head);
head=(LNode*)malloc(sizeof(LNode));
head->next=NULL;
}
//如果一元多项式创建成功就输出该多项式
if(CreatePolynomial(head)==OK)
{
PrintPolynomial(head);
}
system("pause");
break;
case'2':
if(head->next==NULL)
{
printf("使用遍历功能前请先建立链表\n");
system("pause");
}
else
{
printf("\n遍历输出的整数序列为:
\n");
ListTravel(head);
system("pause");
}
break;
case'3':
CreateAndPlus();
break;
case'4':
CreateAndSubtract();
break;
case'5':
system("cls");
if(head->next==NULL)
{
printf("使用项数统计功能之前请先建立一个一元多项式\n");
system("pause");
}
else
{
printf("求项数的多项式为:
\n");
PrintPolynomial(head);
ListCount(head);
}
break;
case'q':
case'Q':
exit(0);
break;
default:
printf("无效输入!
\n");
system("pause");
break;
}
}
return0;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验二 链表 实验报告 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)