数据结构课程设计一元多项式.docx
- 文档编号:8837796
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:24
- 大小:111.67KB
数据结构课程设计一元多项式.docx
《数据结构课程设计一元多项式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计一元多项式.docx(24页珍藏版)》请在冰豆网上搜索。
数据结构课程设计一元多项式
一元多项式计算
1.设计目的
(1)掌握数据结构的应用、算法的编写方法。
(2)掌握类C语言的算法转换成C程序并用VC++上机调试的基本方法。
(3)学会结构体的定义和调用。
(4)学会单链表的初始化和建立。
(5)通过C语言使用链式存储结构实现一元多项式加法、减法和乘法的运算。
按指数降序排列。
(6)本课程设计是为了配合《数据结构》课程的开设,通过设计一完整的程序,使学生掌握数据结构的应用、算法的编写、类C语言的算法转换成C程序并用TC上机调试的基本方法。
2.设计方案论证
2.1.1设计思路
实现的方法是先定义多项式结点的结构,该多项式每个结点由三个元素:
输入的系数、输入的指数、以及指向下一个结点的指针构成。
该链表采用链式存储结构。
然后通过多次的输入,依次得到两个一元多项式的各个项的系数与指数。
该输入以零结尾。
然后通过对结点的判断是否为零后,进行运算或者终止的操作。
再初始化一个链表LC,将LC的各项系数和指数的指针指向LA+LB所得的结果的值,完成了最后的输出。
(1)定义结构体-struct
结构体为表示一个对象的不同属性提供了连贯一致的方法,结构体类型的说明从关键词struct开始,成员可以由各种数据类型混合构成,成员甚至还可以是数组或者其他类型的结构,但是,结构体中不能包含自身定义类型的成员。
使用typedef和struct定义的新类型名称,其用途与内建类型的名称相同,可以用来:
声明和初始化结构体变量;创建并根据自己的意愿初始化结构数组;
(2)单链表的建立
单链表有两个域,data域和next域,一个是存放数据,一个是存放指针而且指向它的后继。
并且还有个head,称表结点,它一般不存放数据,只是做个特殊标记。
表的结束是NULL,也就是最后的那个链域next为空单链表的插入运算有两种,一种是头插法,另一种是尾插法,这里运用的是尾插法
(3)一元多项式的建立
输入多项式采用插头的方式,输入多项式中一个项的系数和指数,就产生一个新的节点,建立起它的右指针,并用头节点指向它;为了判断一个多项式是否结束,定义一个结束标志,并输入非0时就继续,当输入0时,就结束一个多项式的输入
(4)显示一元多项式
如果系数是大于0的话就输出+系数x指数形式;如果系数小于0的话输出系数x指数形式;如果指数为0的话,直接输出系数;如果系数是的话就直接输出+x;如果系数是-1的话直接输出-x输出多项式
(5)一元多项式的加法计算
它从两个多项式的头部开始,两个多项式的某一项都不为空时,如果数相等的话,系数就应该相加;相加的和不为0的话,用头插法建立一个新的节点。
p的指数小于q的指数的话,就应该复制q节点到多项式中。
p的指数大于q的指数的话,就应该复制p节点到多形式中。
当第二个多项式为空时,第一个多项式不为空时,将第一个多项式用心节点产生。
当第一个多项式为空,第二个多项式不为空时,将第二个多项式用新节点产生
(6)一元多项式的减法计算
它从两个多项式的头部开始,两个多项式的某一项都不为空时,如果数相等的话,系数就应该相减;相加的和不为0的话,用头插法建立一个新的节点。
p的指数小于q的指数的话,就应该复制q节点到多项式中。
p的指数大于q的指数的话,就应该复制p节点到多形式中。
并且建立的节点的系数为原来的相反数;当第二个多项式为空时,第一个多项式不为空时,将第一个多项式用心节点产生。
当第一个多项式为空,第二个多项式不为空时,将第二个多项式用新节点产生,并且建立的节点系数为原来的相反数。
(7)一元多项式乘法运算
它从两个多项式的头部开始,两个多项式的某一项都不为空时,如果指数相等的话,系数就应该相乘;相加的和不为0的话,用有插法建立一个新的节点p的指数小于q的指数的话,就应该复制q节点到多形式中。
p的指数大于q的指数的话,就应该复制p节点到多项式中,当第二个多项式为空,第一个多项式不为空时,将第一个多项式用新节点产生。
当第二个多项式为空,将第二个多项式用新节点产生。
输入模块
加法模块
减法模块
乘法模块
输出模块
输入系数和项数,生成多项式
对生成的多项式进行加法运算
对生成的多项式进行减法运算
对生成的多项式进行乘法运算
输出多项式,并释放结点
图1基本模块表
图2总体功能模块图
2.1.2数学模型
在数学上,一个一元多项式Pn(x)可按升幂写成:
Pn(x)=p0+p1x+p2x2+……+pnxn
它由n+1个系数唯一确定,因此,在计算机中它可用一个线性表P来表示:
P=(p0,p1,p2,……,pn)
每一项的指数i隐含在其系数Pi的序号里,每一项的值顺序为各个多项式的系数值。
加法模型
假设Qm(X)是一元m次多项式,同样可用线性表Q来表示:
Q=(q0,q1,q2,……qm)
不失一般性,设m
P(x)=2x4+5x2+3x+1,Q(x)=3x2+1,相加后R(x)=2x4+8x2+3x+2,用一维向量表表示分别为(1,3,5,0,2)+(1,0,3,)=(2,3,8,0,2),写成数学形式即为2x4+8x2+3x+2,结论正确。
减法模型
假设Qm(X)是一元m次多项式,若以线性表Q表示,同上所述:
Q=(q0,q1,q2,……qn)
则两个多项式相减的结果可表示为Rn(x)=P(x)-Q(x),和加法的数学模型相似,可以描述为Rn(x)=P(x)+(-Q(x)),其相减的原理和加法一样,以数学表达式为P(x)-Q(x)=(p0-q0,p1-q1……pm-qm,pm+1……pn)举例说明:
设两个一元多项式分别为P(x)=2x4+5x2+3x+1和Q(x)=3x2+1,Rn(x)=P(x)-Q(x)=2x4+2x2+3x;写成一维向量形式计算为(1,3,5,0,2)-(1,0,3)=(0,3,2,0,2),即证明该算法是可行的。
乘法模型
设两个一元多项式的线性表表示分别为Q=(q0,q1,q2,……qm)和P=(p0,p1,p2,……,pn),则两个多项式相乘的结果可以表示为R=P*Q,为了根据更具一般性,设n>m(以下同),(p0,p1,p2,……,pn)*(q0,q1,q2,……qm)=(p0,p1,p2,……,pn)*q0+(0,p0,p1,p2,……,pn)*q1+……+(0,0,0,0……p0,p1,p2,……,pn)*qm,上述表达式中,每次相乘均要使第一个线性表表示的多项式右移一位,显然,乘最后一项pm时将右移m位0,两个多项式相乘的结果可以表示为m+1个一元n次多项式乘以一个单项式,而单项式乘以一元n次多项式还是一个一元n次多项式,最终将这m+1个一元多项式在相加,所以乘法的数学实现可以依靠一元n次多项式的加法模型。
为了能够清晰的表示上述过程,现简单举例如下:
设P(x)=2x2+3和Q(x)=3x2+2x,用数学表达式相乘的结果R(x)=6x4+4x3+9x2+6x,但在计算机中可以表示为(3,0,2)*(0,2,3)=(3,0,2)*0+(0,3,0,2)*2+(0,0,3,0,2)*3=(0,6,0,4)+(0,0,9,0,6)=(0,6,9,4,6);显然,按照数学模型的定义,可以将最终的结果是(0,6,9,4,6)写成数学式6x4+4x3+9x2+6x,结果与笔算结果一致,该算法是可行的。
2.2.1定义函数及说明
struct-----定义结构体
createPoly-----创建一个多项式链表
outp_poly------输出一个多项式链表。
Addpoly--------多项式和的计算;
Decpoly--------多项式差的计算;
Mulpoly--------多项式积的计算;
DelPoly---------删除多项式;
2.2.2输入一个一元多项式的项数
#include
#include
#include
typedefstructterm{//项的表示,多项式的项作为LinkList的数据元素
floatcoef;//系数
intexpn;//指数
structterm*next;
}term
2.2.3输入n个非零项
term*CreatPolyn(term*P,intm){//算法2.22
//输入m项的系数和指数,建立表示一元多项式的有序链表P
if(m<=0)returnNULL;
term*h=P=(term*)malloc(sizeof(term)),*q;
P->coef=0.0;
inti;
printf("依次输入%d个非零项\n",m);
for(i=1;i<=m;++i){//依次输入m个非零项
scanf("%f%d",&P->coef,&P->expn);
if(P->coef)
q=P;
P=P->next=(term*)malloc(sizeof(term));
}
q->next=NULL;
free(P);
returnh;
}//CreatPolyn
term*selsort(term*h){
term*g,*p,*q;
if(!
h)returnNULL;
floatf;
inti,fini=1;
for(g=h;g->next&&fini;g=g->next){
fini=0;
for(p=h,q=h->next;q;p=p->next,q=q->next)
if(p->expn
f=p->coef;i=p->expn;
p->coef=q->coef;p->expn=q->expn;
q->coef=f;q->expn=i;
fini=1;
}
}
for(g=h,p=g->next;p;)
if(g->expn==p->expn){
g->coef+=p->coef;
g->next=p->next;
q=p;
p=p->next;
free(q);
}
elseif(g->next){
g=g->next;
p=p->next;
}
returnh;
}
2.2.4排序
表示多项式,最好按照习惯,以次数的降序来排列各项。
通过Xiang*Paixu(Xiang*h)函数,使一元多项式按照次数从大到小排列输出。
其算法如下:
Xiang*Paixu(Xiang*h)
{
flag=1;
for(g=h;g->next&&flag;g=g->next)
{
flag=0;
for(p=h,q=h->next;q;p=p->next,q=q->next)
if(p->Zhishu
{
p<==>q;
flag=1;
}
}
for(g=h,p=g->next;p;)
{
if(g->Zhishu==p->Zhishu)
{
g=g+p;
}
else
{
g=g->next;
p=p->next;
}
}
returnh;
}
然后调用Xiang*Jiafa(Xiang*Pa,Xiang*Pb)函数,再通过调用其子函数Xiang*APolyn(Xiang*Pa,Xiang*Pb),实现多项式加法,即Pa=Pa+Pb,利用两个多项式的结点构成"多项式的和"。
通过对Xiang*Jianfa(Xiang*Pa,Xiang*Pb)函数和Xiang*BPolyn(Xiang*Pa,Xiang*Pb)函数的调用,实现了多项式的减法,即Pa=Pa-Pb,利用两个多项式的结点构成"多项式的差"。
.通过调用Xiang*Chengfa(Xiang*Pa,Xiang*Pb)函数和Xiang*CPolyn(Xiang*Pa,Xiang*Pb)函数,实现了多项式的乘法运算,即Pa=Pa*Pb,利用两个多项式的结点构成"多项式的积"。
通过对输出函数voidShuchu(Xiang*P)的调用,把各一元多项式和一元多项式的计算结果输出来
2.2.5单连表的抽象数据类型定义:
ADTList{
数据对象:
D={ai|ai∈ElemSet,i=1,2,…,n,n≥0}
数据关系:
R1={
基本操作:
InitList(﹠L)
//操作结果:
构造一个空的线性表
CreatPolyn(&L)
//操作结果:
构造一个以单连表存储的多项试
DispPolyn(L)
//操作结果:
显示多项试
Polyn(&pa,&pb)
//操作结果:
显示两个多项试相加,相减的结果
}ADTList
2.2.6加法,减法,乘法模块
加法模块
函数功能:
实现两个多项式想加,并将计算结果存储于pa中
原理:
将指数相同的项的系数加
pa,与pb的幂次序都要求是升序,否则可能得到错误的结果
/加法模块函数如下:
voidaddPoly(Linkpa,Linkpb)
{
Linkpc,pre,u;
floatsum;
pc=pa;
pre=pa;
pa=pa->next;
u=pb;
pb=pb->next;
free(u);
while(pa&&pb){
if(pa->exp
pre=pa;
pa=pa->next;
}elseif(pa->exp>pb->exp){
u=pb->next;
pb->next=pa;
pre->next=pb;
pre=pb;
pb=u;
}else{
sum=pa->coef+pb->coef;//指数相加
if(sum!
=0.0){
pa->coef=sum;
pre=pa;
}else{
pre->next=pa->next;
free(pa);
}
pa=pre->next;
u=pb;
pb=pb->next;
free(u);
}
}
if(pb)pre->next=pb;
}//EndaddPoly
理论分析:
加法模块的实现比较简单,在这里需要说明的是,对同指数的项进行运算,所以所加法实际上是四则运算的基础
减法模块:
函数功能:
实现两个多项式相减
原理:
与加法类似,将指数相同的指数相减
乘法模块:
理论分析:
多项式乘法可以由两个一元多项式相加的算法来实现,因为乘法运算可以分解为一系列的加法运算。
假设A(x)和B(x)为如下的多项式,则
M(x)=A(x)*B(x)
=A(x)*[b1xe1+b2xe2+……+bnxen]
则会分解成很多个单项式乘以多项式的问题,即每一项都是一个一元多项式,最后又是一元单项式相加的问题。
2.3设计方法
1.输入一元多项式的个数
2.输入该多项式的非零项并显示出多项式
3.进行多项式的加减乘运算
2.4源程序
#include
#include
#include
typedefstructterm{//项的表示,多项式的项作为LinkList的数据元素
floatcoef;//系数
intexpn;//指数
structterm*next;
}term;
term*CreatPolyn(term*P,intm){//算法2.22
//输入m项的系数和指数,建立表示一元多项式的有序链表P
if(m<=0)returnNULL;
term*h=P=(term*)malloc(sizeof(term)),*q;
P->coef=0.0;
inti;
printf("依次输入%d个非零项\n",m);
for(i=1;i<=m;++i){//依次输入m个非零项
scanf("%f%d",&P->coef,&P->expn);
if(P->coef)
q=P;
P=P->next=(term*)malloc(sizeof(term));
}
q->next=NULL;
free(P);
returnh;
}//CreatPolyn
term*selsort(term*h){
term*g,*p,*q;
if(!
h)returnNULL;
floatf;
inti,fini=1;
for(g=h;g->next&&fini;g=g->next){
fini=0;
for(p=h,q=h->next;q;p=p->next,q=q->next)
if(p->expn
f=p->coef;i=p->expn;
p->coef=q->coef;p->expn=q->expn;
q->coef=f;q->expn=i;
fini=1;
}
}
for(g=h,p=g->next;p;)
if(g->expn==p->expn){
g->coef+=p->coef;
g->next=p->next;
q=p;
p=p->next;
free(q);
}
elseif(g->next){
g=g->next;
p=p->next;
}
returnh;
}
voidPrintfPoly(term*P){
term*q=P;
if(!
q){
putchar('0');
return;
}
if(q->coef!
=1){
printf("%g",q->coef);
if(q->expn==1)putchar('X');
elseif(q->expn)printf("X^%d",q->expn);
}
elseif(!
q->expn)putchar('1');
elseif(q->expn==1)putchar('X');
elseprintf("X^%d",q->expn);
q=q->next;
while(q){
if(q->coef>0)putchar('+');
if(q->coef!
=1){
printf("%g",q->coef);
if(q->expn==1)putchar('X');
elseif(q->expn)printf("X^%d",q->expn);
}
elseif(!
q->expn)putchar('1');
elseif(q->expn==1)putchar('X');
elseprintf("X^%d",q->expn);
q=q->next;
}
}
Compare(term*a,term*b){
if(a->expn
if(a->expn>b->expn)return1;
return0;
}
term*APolyn(term*Pa,term*Pb){//算法2.23
//多项式加法:
Pa=Pa+Pb,利用两个多项式的结点构成"和多项式"。
term*h,*qa=Pa,*qb=Pb,*p,*q;
floatsum;
h=p=(term*)malloc(sizeof(term));
p->next=NULL;
while(qa&&qb){//Pa和Pb均非空
switch(Compare(qa,qb)){
case-1:
//多项式PA中当前结点的指数值小
p->next=qb;
p=qb;
qb=qb->next;
break;
case0:
//两者的指数值相等
sum=qa->coef+qb->coef;
if(sum!
=0.0){//修改多项式PA中当前结点的系数值
p->next=qa;
qa->coef=sum;
p=qa;
qa=qa->next;
}
else{//删除多项式PA中当前结点
q=qa;
qa=qa->next;
free(q);
}
q=qb;
qb=qb->next;
free(q);
break;
case1:
//多项式PB中当前结点的指数值小
p->next=qa;
p=qa;
qa=qa->next;
break;
}//switch
}//while
if(Pa)p->next=qa;//链接Pa中剩余结点
if(Pb)p->next=qb;//链接Pb中剩余结点
q=h;
h=h->next;
free(q);
returnh;
}//APolyn
term*A(term*Pa,term*Pb){
intn;
puts("再输入一一元多项式的项数");
scanf("%d",&n);
Pb=CreatPolyn(Pb,n);
Pb=selsort(Pb);
PrintfPoly(Pa);
if(Pb&&Pb->coef>0)printf("+");
PrintfPoly(Pb);
Pa=APolyn(Pa,Pb);
printf("=");
Pa=selsort(Pa);
PrintfPoly(Pa);
returnPa;
}
term*BPolyn(term*Pa,term*Pb){//算法2.23
//多项式减法:
Pa=Pa-Pb,利用两个多项式的结点构成"差多项式"。
term*p=Pb;
while(p){
p->coef*=-1;
p=p->next;
}
returnAPolyn(Pa,P
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 一元 多项式
![提示](https://static.bdocx.com/images/bang_tan.gif)