#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERLOW -2
/*--------------------------------------
Data Element
--------------------------------------*/
typedef struct{
float coef;//系数
int expn;//指数
}term,ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*Link,*Position;
typedef struct HeadNode{
Link head,tail;
int len;
}LinkList;
typedef LinkList polynomail;
typedef int status;
/*---------------------------------------
OP of Link List
---------------------------------------*/
status MakeNode( Link &p, ElemType e){
p=(Link)malloc(sizeof(LNode));
p->data=e;
return OK;
}
status InitList( LinkList &L){
L.head=(Link)malloc(sizeof(LNode));
ElemType e;
e.coef=0, e.expn=-1;
L.head->data=e;
L.head->next=NULL;
L.tail=L.head;
L.len=0;
return OK;
}
status SetCurElem(Link &p,ElemType e){
p->data=e;
return OK;
}
status InsAfter( Link q, Link s){
//将结点s插入到结点q之后
s->next=q->next;
q->next=s;
return OK;
}
status ListEmpty(LinkList P){
if(P.head->next==NULL) return TRUE;
return FALSE;
}
status Append( LinkList &L, Link s){
//将一串元素s插入到链表L的末尾,同时改变链表的长度以及尾指针
L.tail->next=s;
L.len++;
while(s->next!=NULL){
s=s->next;L.len++;
}
L.tail=s;
return OK;
}
int cmp( term e1, term e2){
if(e1.expn<e2.expn) return -1;
if(e1.expn==e2.expn) return 0;
if(e1.expn>e2.expn) return 1;
}
Position GetHead( LinkList L){
return L.head;
}
Position GetLast( LinkList L){
return L.tail;
}
Position NextPos( LinkList L, Link p){
p=p->next;
return p;
}
status DelFirst( Link h, Link q){
//已知h是头结点,删除h后的第一个结点q
h->next=q->next;
return OK;
}
/*------------------------------------------
OP of polynomial
------------------------------------------*/
void CreatePolyn(polynomail &P,int m){
/*CreatePolyn(polynomail &P,int m)--使用尾差法创建一个具有m项的多项式P,
它为P.len中存放有多项式的项数,P.tail指向多项式的尾结点,P.head为多项式的
头结点,头结点不存放数据,统一初始化为P.head->data.coef=0,
P.head->data.expn=-1。调用时需要按照从高次项向低次项的顺序输入数据。
*/
InitList(P);
Link s,q;
term e;
int i;
printf("\nPlease input %d terms in order:\n",m);
for(i=1;i<=m;i++){
scanf("%f%d",&e.coef,&e.expn);
if(MakeNode(s,e)){
q=GetLast(P);InsAfter(q,s); P.tail=s; P.len++;
}
}
printf("\nCreate polynomail succeed!\n");
}
int PrintPolyn( polynomail &P){
//遍历打印多项式
Link p=P.head;
if(p->next==NULL) {
printf("\nEmpty LinkList!\n"); return OK;
}
printf("\ncoef\texpn\n");
while(p!=NULL){
if(p->data.expn>=0) printf("%.2f\t%d\n",p->data.coef,p->data.expn);
p=p->next;
}
printf("\nPrint succeed!\n");
return OK;
}
void AddPolyn( polynomail &Pa, polynomail &Pb){
/*Pa=Pa+Pb,最终结果保存在Pa中。算法的时间复杂度取决于两个多项式Pa,Pb
之间最高次项较低的那个多项式的长度。最坏情况下,假如每次循环都需要进系数相加,
case 0中所有操作的时间复杂度均为O(1),循环外的Append(Pa,Pb)的时间复杂度也是
O(1),因此AddPolyn(Pa,Pb)的时间复杂度为O(n)
*/
Link ha=GetHead(Pa); //头结点h不存储term
Link hb=GetHead(Pb);
Link qa=NextPos(Pa,ha);
Link qb=NextPos(Pb,hb);
while(qa!=NULL && qb!=NULL){
term a= qa->data;
term b= qb->data;
switch(cmp(a,b)){ //cmp比较的是term之间指数的大小
case 1:
ha=qa; qa=NextPos( Pa,qa); break;
case 0:
term sum;
sum.expn=a.expn;
sum.coef=a.coef+b.coef;
if(sum.coef!=0){
SetCurElem( qa,sum); ha=qa;}
else{
DelFirst(ha,qa); free(qa);}
DelFirst(hb,qb); free(qb); qb=NextPos(Pb,hb);
qa=NextPos(Pa,ha); break;
case -1:
DelFirst(hb,qb); InsAfter(ha,qb);Pa.len++;
qb=NextPos(Pb,hb); ha=NextPos(Pa,ha);break;
}
}
if(!ListEmpty(Pb)) Append(Pa,qb);
}
void SubPolyn( polynomail &Pa, polynomail &Pb){
/*Pa=Pa-Pb,最终结果保存在Pa中,Pb被释放。SubPolyn(Pa,Pb)相对于
AddPolyn(Pa,Pb),只多了一个操作:将多项式Pb的系数取负号。该操作的
的时间复杂度为O(n),因此SubPolyn(pa,pb)的时间复杂度为O(n)。
*/
Link ha=GetHead(Pa); //头结点h不存储term
Link hb=GetHead(Pb);
Link qa=NextPos(Pa,ha);
Link qb=NextPos(Pb,hb);
while(qb!=NULL){
qb->data.coef=-qb->data.coef; qb=NextPos(Pb,qb);
}
qb=NextPos(Pb,hb);
while(qa!=NULL && qb!=NULL){
term a= qa->data;
term b= qb->data;
switch(cmp(a,b)){ //cmp比较的是term之间指数的大小
case 1:
ha=qa; qa=NextPos( Pa,qa); break;
case 0:
term sum;
sum.expn=a.expn;
sum.coef=a.coef+b.coef;
if(sum.coef!=0){
SetCurElem( qa,sum); ha=qa;}
else{
DelFirst(ha,qa); free(qa);}
DelFirst(hb,qb); free(qb); qb=NextPos(Pb,hb);
qa=NextPos(Pa,ha); break;
case -1:
DelFirst(hb,qb); InsAfter(ha,qb);Pa.len++;
qb=NextPos(Pb,hb); ha=NextPos(Pa,ha);break;
}
}
if(!ListEmpty(Pb)) Append(Pa,qb);
free(hb);
}
void MultiPolyn( polynomail &Pa, polynomail &Pb){
/*Pa=Pa*Pb,最终结果保存在Pa中。MultiPolyn(Pa,Pb)的基本操作为
AddPolyn(Pd,Pc)(复杂度为O(n))和多形式和单项式的乘法(复杂度为O(n))
基本操作位于一个循环数为Pb.len的循环中,因此MultiPolyn(Pa,Pb)的时间复杂度
为O(n^2)。
*/
polynomail Pc,Pd;
Link ha=GetHead(Pa);
Link hb=GetHead(Pb);
Link qa=NextPos(Pa,ha);
Link qb=NextPos(Pb,hb);
Link s,qc;
int i,j,lena=Pa.len,lenb=Pb.len;
term a,b,c;
InitList(Pd);
for(i=1;i<=lenb;i++){
InitList(Pc); //Pc用于记录多项式Pa每次乘以Pb各项所得到的多项式
for(j=1;j<=lena;j++){
a= qa->data;
b= qb->data;
c.coef=a.coef*b.coef; c.expn=a.expn+b.expn;
if(MakeNode(s,c)){
qc=GetLast(Pc);InsAfter(qc,s); Pc.tail=s; Pc.len++;
}//if
qa=NextPos(Pa,qa);
}//for(j)
qa=NextPos(Pa,ha); //注意此时qa一定要指向多项式Pa的首项
qb=NextPos(Pb,qb);
AddPolyn(Pd,Pc); //Pd+=Pc
}//for(i)
Pa=Pd;
}
void DivPolyn( polynomail &Pa, polynomail &Pb){
/*Pa=Pd*Pb+Pa,最终的商存储在Pd中,余式存储在Pa中。DivPolyn(Pa,Pb)的
基本操作为MultiPolyn(Pc,Pb),该基本操作位于一个循环数为多项式Pa和Pb最高
项次数之差的循环之中。因此,考虑最坏情况,该算法的时间复杂度为O(n^3)。
*/
polynomail Pc,Pd;
Link ha=GetHead(Pa);
Link hb=GetHead(Pb);
Link qa=NextPos(Pa,ha);
Link qb=NextPos(Pb,hb);
Link s,qc;
term a,b,c;
InitList( Pd);
a=qa->data; b=qb->data;
while(a.expn>=b.expn){
InitList (Pc);
c.expn=a.expn-b.expn;
c.coef=a.coef/b.coef;
if(MakeNode(s,c)){
qc=GetLast(Pc);InsAfter(qc,s); Pc.tail=s; Pc.len++;
}
AddPolyn( Pd,Pc); MultiPolyn( Pc,Pb); SubPolyn( Pa,Pc); //Pd用来存储商,SubPolyn()中Pc会被free
qa=NextPos(Pa,qa); //Pd+=Pc,Pc*=Pb,Pa-=Pc,最终Pa中存储的是余式
a=qa->data;
}//while
printf("The quotient polynomail is :\n");
PrintPolyn(Pd);
printf("The complement minor is :\n");
PrintPolyn(Pa);
}
/*-------------------------------------
function main
--------------------------------------*/
/*
int main(){
//test for AddPolyn(),SubPolyn() and MultiPolyn()
polynomail P1;
polynomail P2;
CreatePolyn(P1,2);
CreatePolyn(P2,4);
printf("\nThe length of poly1 is %d\n",P1.len);
PrintPolyn( P1);
printf("\nThe length of poly2 is %d\n",P2.len);
PrintPolyn( P2);
SubPolyn( P1,P2);
PrintPolyn( P1);
printf("\nThe length of poly1 is %d\n",P1.len);
return OK;
}
*/
int main(){
//test for DivPolyn()
polynomail P1;
polynomail P2;
CreatePolyn(P1,3);
CreatePolyn(P2,2);
printf("\nThe length of poly1 is %d\n",P1.len);
PrintPolyn( P1);
printf("\nThe length of poly2 is %d\n",P2.len);
PrintPolyn( P2);
DivPolyn( P1,P2);
return OK;
}