1、一、课程题目一元稀疏多项式计算器二、 需求分析1、一元稀疏多项式简单计算器的功能是:1.1 输入并建立多项式;1.2 输出多项式,输出形式为整数序列:n,c1,e1,c2,e2,cn,en,其中 n 是多项式的项数,ci 和 ei 分别是第 i 项的系数和指数,序列按指数降序排列; 1.3 多项式 a 和 b 相加,建立多项式 a+b;1.4 多项式 a 和 b 相减,建立多项式 a-b。1.5 多项式 a 和 b 相乘,建立乘积多项式 ab。2、设计思路:2.1 定义线性表的动态分配顺序存储结构;2.2 建立多项式存储结构,定义指针*next2.3 利用链表实现队列的构造。每次输入一项的系数
2、和指数,可以输出构造的一元多项式2.4 演示程序以用户和计算机的对话方式执行,即在计算机终站上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运行命令;最后根据相应的输入数据(滤去输入中的非法字符)建立的多项式以及多项式相加的运行结果在屏幕上显示。多项式显示的格式为:c1xe1+c2xe2+cnxen3、设计思路分析要解决多项式相加,必须要有多项式,所以必须首先建立两个多项式,在这里采用链表的方式存储链表,所以我将结点结构体定义为序数 coef 指数 expn 指针域 next运用尾插法建立两条单链表,以单链表 polyn p 和 polyn h 分别表示两个一元多项式 a 和 b,a
3、+b 的求和运算等同于单链表的插入问题(将单链表polyn p 中的结点插入到单链表 polyn h 中),因此“和多项式”中的结点无须另生成。为了实现处理,设 p、q 分别指向单链表 polya 和 polyb 的当前项,比较p、q 结点的指数项,由此得到下列运算规则: 若 p-expnexpn,则结点 p 所指的结点应是“和多项式”中的一项,令指针 p 后移。 若 p-expn=q-expn,则将两个结点中的系数相加,当和不为 0 时修改结点 p 的系数。 若 p-expnq-expn,则结点 q 所指的结点应是“和多项式”中的一项,将结点 q 插入在结点 p 之前,且令指针 q 在原来的
4、链表上后移。4、数据测试(1) 、(2x+5x8-3.1x11)+(7-5x8+11x9)=(-3.1x11+11x9+2x+7);(2) 、(2x+5x8-3.1x11)-(7-5x8+11x9)=-3.1x11-11x9+10x8+12x-7;(3)(2x+5x8-3.1x11)*(7-5x8+11x9)=34.1x20+15.5x19+55x17-25x16-21.7x11+22x10-10x9+35x8+14x三、概要设计1、元素类型、结点类型和指针类型:typedef struct Polynomialfloat coef; /系数int expn; /指数struct Polyno
5、mial *next;*Polyn,Polynomial;2、建立一个头指针为 head、项数为 m 的一元多项式, 建立新结点以接收数据, 调用 Insert 函数插入结点:Polyn CreatePolyn(Polyn head,int m) int i;Polyn p;p=head=(Polyn)malloc(sizeof(struct Polynomial);head-next=NULL;for(i=0;icoef,Insert(p,head); return head;3、主函数和其他函数:void main()int m,n,a,x;char flag;Polyn pa=0,pb=
6、0,pc; 4、数据结构:带头结点单链表抽象数据类型的结点结构定义如下:typedef struct Polynode /多项式结点int coef; /系数int exp; /指数Polynode *next;Polynode ,*Polylist;5.模块划分:(1) 带头结点的多项式的建立函数 Polylist Polycreate()(2) 带头结点的多项式的降幂输出函数 void printf(Polylist poly)(3) 带头结点的多项式的相加函数 Polylist Polyadd(Polylist a,Polylist b)(4) 带头结点的多项式的相减函数 Polylis
7、t Polysub(Polylist a,Polylist b)(5) 主函数 void main()四、程序代码:#include#include /定义多项式的项typedef struct Polynomialfloat coef; /系数int expn; /指数struct Polynomial *next;*Polyn,Polynomial;void Insert(Polyn p,Polyn h) if(p-coef=0) free(p); /系数为 0 的话释放结点elsePolyn q1,q2;q1=h;q2=h-next;while(q2q2=q2-next;if(q2fre
8、e(p);if(!q2-coef) /系数为 0 的话释放结点q1-next=q2-next;free(q2);else /指数为新时将结点插入p-next=q2;q1-next=p;Polyn CreatePolyn(Polyn head,int m) /建立一个头指针为 head、项数为 m 的一元多项式int i;Polyn p;p=head=(Polyn)malloc(sizeof(struct Polynomial);head-next=NULL;for(i=0;icoef,Insert(p,head); /调用 Insert 函数插入结点return head;void Destr
9、oyPolyn(Polyn p) /销毁多项式 pPolyn q1,q2;q1=p-next;q2=q1-next;while(q1-next)free(q1);q1=q2;q2=q2-next;void PrintPolyn(Polyn P)Polyn q=P-next; int flag=1; /项数计数器if(!q) /若多项式为空,输出 0putchar(0); printf(“n“);return; while(q)if(q-coef0 /系数大于 0 且不是第一项if(q-coef!=1 if(q-expn=1) putchar(X);else if(q-expn) printf(
10、“X%d“,q-expn);elseif(q-coef=1)if(!q-expn) putchar(1); else if(q-expn=1) putchar(X); else printf(“X%d“,q-expn);if(q-coef=-1)if(!q-expn) printf(“-1“); else if(q-expn=1) printf(“-X“); else printf(“-X%d“,q-expn);q=q-next; flag+;printf(“n“);int compare(Polyn a,Polyn b)if(aelse if(!a|a-expnexpn) return -1
11、;else return 0;else if(!a /a 多项式已空,但 b多项式非空else return 1; /b 多项式已空,但 a多项式非空Polyn AddPolyn(Polyn pa,Polyn pb) /求解并建立多项式a+b,返回其头指针Polyn qa=pa-next;Polyn qb=pb-next;Polyn headc,hc,qc;hc=(Polyn)malloc(sizeof(struct Polynomial); /建立头结点hc-next=NULL;headc=hc;while(qa|qb)qc=(Polyn)malloc(sizeof(struct Polyn
12、omial);switch(compare(qa,qb)case 1:qc-coef=qa-coef;qc-expn=qa-expn;qa=qa-next;break;case 0: qc-coef=qa-coef+qb-coef;qc-expn=qa-expn;qa=qa-next;qb=qb-next;break;case -1:qc-coef=qb-coef;qc-expn=qb-expn;qb=qb-next;break; if(qc-coef!=0)qc-next=hc-next;hc-next=qc;hc=qc;else free(qc); /当相加系数为 0 时,释放该结点ret
13、urn headc;Polyn SubtractPolyn(Polyn pa,Polyn pb) /求解并建立多项式 a-b,返回其头指针Polyn h=pb;Polyn p=pb-next;Polyn pd;while(p) /将 pb 的系数取反p-coef*=-1;p=p-next;pd=AddPolyn(pa,h);for(p=h-next;p;p=p-next) /恢复 pb 的系数p-coef*=-1;return pd;Polyn MultiplyPolyn(Polyn pa,Polyn pb) /求解并建立多项式 a*b,返回其头指针Polyn hf,pf;Polyn qa=p
14、a-next;Polyn qb=pb-next;hf=(Polyn)malloc(sizeof(struct Polynomial);/建立头结点hf-next=NULL;for(;qa;qa=qa-next)for(qb=pb-next;qb;qb=qb-next)pf=(Polyn)malloc(sizeof(struct Polynomial);pf-coef=qa-coef*qb-coef;pf-expn=qa-expn+qb-expn;Insert(pf,hf); /调用 Insert 函数以合并指数相同的项return hf;void main()int m,n,a,x;char
15、flag;Polyn pa=0,pb=0,pc;printf(“请输入 a 的项数:“);scanf(“%d“,pa=CreatePolyn(pa,m); /建立多项式 aprintf(“请输入 b 的项数:“);scanf(“%d“,pb=CreatePolyn(pb,n); /建立多项式 b/输出菜单printf(“ *n“);printf(“ * 多项式操作程序 *n“);printf(“ * *n“);printf(“ * A:输出多项式 a B:输出多项式 b *n“);printf(“ * *n“);printf(“ * C:输出 a+b D:输出 a-b *n“);printf(
16、“ * *n“);printf(“ * E:输出 a*b F:退出程序 *n“);printf(“ * *n“);printf(“ *n“);while(a)printf(“n 请选择操作:“);scanf(“ %c“, switch(flag)caseA:casea:printf(“n 多项式 a=“);PrintPolyn(pa);break;caseB:caseb:printf(“n 多项式 b=“);PrintPolyn(pb);break;caseC:casec:pc=AddPolyn(pa,pb);printf(“n a+b=“);PrintPolyn(pc);break;case
17、D:cased:pc=SubtractPolyn(pa,pb);printf(“n a-b=“);PrintPolyn(pc);break;caseE:casee:pc=MultiplyPolyn(pa,pb);printf(“n a*b=“);PrintPolyn(pc);break;caseF:casef:printf(“n 感谢使用此程序!n“);DestroyPolyn(pa);DestroyPolyn(pb);a=0;break;default:printf(“n 您的选择错误,请重新选择!n“);五、调用关系图主函数P a p b p c建立链表P o l y n C r e a
18、t e P o l y n ( P o ly n h e a d , i n t m )多项式相加P o l y n A d d P o l y n ( P o l y n p a , P o l y n p b )输出多项式W h i l e P r i n t f ( “ ” ) ;返回*head返回*hcreturnheadc*h项数m六、 调试分析1、由于对算法的推敲不足,在程序调试出气,犯了些小错误,如指针定义时忽略了“*” ;2、算法的分析建立多项式的时间复杂度为 O(n),降幂输出多项式序列算法,由于是对指数做的循环,每次循环都需要从首元结点查找到表尾,假设多项式开始为升幂排列,
19、如 x1+x2+x3+x4+xn,(这里 n=20)其时间复杂度为 n(n+1)/2,若指数不是连续的,则其时间复杂度加上 O(n),所以此算法的时间复杂度为 O(n2) 。假设 a 有 M 项,b 有 N 项,则加法和减法算法的时间复杂度度为 M+N,算法中两多项式相加和相减时,a,b 均需按升幂顺序输入结点。七、 测试结果(1) 、(2x+5x8-3.1x11)+(7-5x8+11x9)=(-3.1x11+11x9+2x+7)(2) 、(2x+5x8-3.1x11)-(7-5x8+11x9)=-3.1x11-11x9+10x8+12x-7;(3)(2x+5x8-3.1x11)*(7-5x8+11x9)=34.1x20+15.5x19+55x17-25x16-21.7x11+22x10-10x9+35x8+14x