if(!
p||compare(p->data,e)>0)//到表尾或compare(p->data,e)>0
{
*q=pp;
return0;
}
else//找到
{
*q=p;
return1;
}
}
//h指向L的一个结点,把h当做头结点,删除链表中的第一个结点并以q返回。
//若链表为空(h指向尾结点),q=NULL,返回0
intDelFirst(LinkList*L,Linkh,Link*q)
{
*q=h->next;
if(*q)//链表非空
{
h->next=(*q)->next;
if(!
h->next)//删除尾结点
(*L).tail=h;//修改尾指针
(*L).len--;
return1;
}
else
return0;//链表空
}
//分配由p指向的值为e的结点,并返回1;若分配失败。
则返回0
intMakeNode(Link*p,ElemTypee)
{
*p=(Link)malloc(sizeof(LNode));//动态分配一个Link空间
if(!
*p)
return0;
(*p)->data=e;//赋值
return1;
}
//释放p所指结点
voidFreeNode(Link*p)
{
free(*p);//老规矩,先释放存储空间,然后置空
*p=NULL;
}
//h指向L的一个结点,把h当做头结点,将s所指结点插入在第一个结点之前
//头结点没有数据域,而第一个结点是h->next
intInsFirst(LinkList*L,Linkh,Links)
{
s->next=h->next;
h->next=s;
if(h==(*L).tail)//如果h指向尾结点
(*L).tail=h->next;//修改尾指针
(*L).len++;
return1;
}
//按有序判定函数compare()的约定,将值为e的结点插入或合并到升序
//链表L的适当位置
intOrderInsertMerge(LinkList*L,ElemTypee,int(*compare)(term,term))
{
Positionq,s;
if(LocateElemP(*L,e,&q,compare))//L中存在该指数项
{
q->data.coef+=e.coef;//改变当前结点系数的值
if(!
q->data.coef)//系数为0
{
//删除多项式L中当前结点
s=PriorPos(*L,q);//s为当前结点的前驱
if(!
s)//q无前驱
s=(*L).head;
DelFirst(L,s,&q);
FreeNode(&q);
}
return1;
}
else//生成该指数项并插入链表
if(MakeNode(&s,e))//生成结点成功
{
InsFirst(L,q,s);
return1;
}
else//生成结点失败
return0;
}
//依a的指数值<、=或>b的指数值,分别返回-1、0或+1
//CreatPolyn()的实参
intcmp(terma,termb)
{
if(a.expn==b.expn)
return0;
else
return(a.expn-b.expn)/abs(a.expn-b.expn);
}
//构造一个空的线性链表
intInitList(LinkList*L)
{
Linkp;
p=(Link)malloc(sizeof(LNode));//生成头结点
if(p)
{
p->next=NULL;
//将头尾结点都分配好,并将其下一结点置空
(*L).head=(*L).tail=p;
(*L).len=0;//初始为0
return1;
}
else//分配失败返回
return0;
}
//算法2.22P42
//输入m项的系数和指数,建立表示一元多项式的有序链表P
voidCreatPolyn(polynomial*P,intm)
{
Positionq,s;
terme;
inti;
InitList(P);
printf("请依次输入%d个系数,指数:
(空格)\n",m);
for(i=1;i<=m;++i)
{
//依次输入m个非零项(可按任意顺序)
scanf("%f%d",&e.coef,&e.expn);
//当前链表中不存在该指数项,cmp是实参
if(!
LocateElemP(*P,e,&q,cmp))
if(MakeNode(&s,e))//生成结点并插入链表
InsFirst(P,q,s);
}
}
//返回线性链表L中头结点的位置
PositionGetHead(LinkListL)
{
returnL.head;
}
//已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的位置
//若无后继,则返回NULL
PositionNextPos(Linkp)
{
returnp->next;
}
//已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值
ElemTypeGetCurElem(Linkp)
{
returnp->data;
}
//将指针s(s->data为第一个数据元素)所指(彼此以指针相链,以NULL结尾)的
//一串结点链接在线性链表L的最后一个结点之后,并改变链表L的尾指针指向新
//的尾结点
intAppend(LinkList*L,Links)
{
inti=1;//记录s为头的串结点个数
(*L).tail->next=s;//尾结点指向s
while(s->next)
{
s=s->next;
i++;
}
(*L).tail=s;
(*L).len+=i;
return1;
}
//若线性链表L为空表,则返回1,否则返回0
intListEmpty(LinkListL)
{
if(L.len)
return0;
else
return1;
}
//将线性链表L重置为空表(头尾结点相同为空表),并释放原链表的结
//点空间,不释放头尾结点,只是置空而已
intClearList(LinkList*L)
{
Linkp,q;
if((*L).head!
=(*L).tail)//不是空表
{
p=q=(*L).head->next;
(*L).head->next=NULL;
while(p!
=(*L).tail)
{
p=q->next;
free(q);
q=p;
}
free(q);
(*L).tail=(*L).head;
(*L).len=0;
}
return1;
}
//销毁线性链表L,L不再存在
intDestroyList(LinkList*L)
{
ClearList(L);//清空链表(头尾结点并没有释放)
FreeNode(&(*L).head);//再释放头尾结点
(*L).tail=NULL;
(*L).len=0;
return1;
}
//算法2.23P43
//多项式加法:
Pa=Pa+Pb,并销毁一元多项式Pb
voidAddPolyn(polynomial*Pa,polynomial*Pb)
{
Positionha,hb,qa,qb;
terma,b;
ha=GetHead(*Pa);
hb=GetHead(*Pb);//ha和hb分别指向Pa和Pb的头结点
qa=NextPos(ha);
qb=NextPos(hb);//qa和qb分别指向Pa和Pb中当前结点(现为第一个结点)
while(!
ListEmpty(*Pa)&&!
ListEmpty(*Pb)&&qa)
{//Pa和Pb均非空且ha没指向尾结点(qa!
=0)
a=GetCurElem(qa);
b=GetCurElem(qb);//a和b为两表中当前比较元素
switch(cmp(a,b))
{
case-1:
ha=qa;//多项式Pa中当前结点的指数值小
qa=NextPos(ha);//ha和qa均向后移一个结点
break;
case0:
qa->data.coef+=qb->data.coef;
//两者的指数值相等,修改Pa当前结点的系数值
if(qa->data.coef==0)//系数和为0,则删除多项式Pa中当前结点
{
DelFirst(Pa,ha,&qa);
FreeNode(&qa);
}
else
ha=qa;
DelFirst(Pb,hb,&qb);
FreeNode(&qb);
qb=NextPos(hb);
qa=NextPos(ha);
break;
case1:
DelFirst(Pb,hb,&qb);//多项式Pb中当前结点的指数值小
InsFirst(Pa,ha,qb);
ha=ha->next;
qb=NextPos(hb);
}
}
if(!
ListEmpty(*Pb))
{
(*Pb).tail=hb;
Append(Pa,qb);//链接Pb中剩余结点
}
DestroyPolyn(Pb);//销毁Pb
}
//另一种多项式加法的算法:
Pa=Pa+Pb,并销毁一元多项式Pb
voidAddPolyn1(polynomial*Pa,polynomial*Pb)
{
Positionqb;
termb;
qb=GetHead(*Pb);//qb指向Pb的头结点
qb=qb->next;//qb指向Pb的第一个结点
while(qb)
{
b=GetCurElem(qb);
OrderInsertMerge(Pa,b,cmp);
qb=qb->next;
}
DestroyPolyn(Pb);//销毁Pb
}
//一元多项式系数取反
voidOpposite(polynomialPa)
{
Positionp;
p=Pa.head;
while(p->next)
{
p=p->next;
p->data.coef*=-1;
}
}
//多项式减法:
Pa=Pa-Pb,并销毁一元多项式Pb
voidSubtractPolyn(polynomial*Pa,polynomial*Pb)
{
Opposite(*Pb);
AddPolyn(Pa,Pb);
}
//多项式乘法:
Pa=PaPb,并销毁一元多项式Pb
voidMultiplyPolyn(polynomial*Pa,polynomial*Pb)
{
polynomialPc;
Positionqa,qb;
terma,b,c;
InitList(&Pc);
qa=GetHead(*Pa);
qa=qa->next;
while(qa)
{
a=GetCurElem(qa);
qb=GetHead(*Pb);
qb=qb->next;
while(qb)
{
b=GetCurElem(qb);
c.coef=a.coef*b.coef;
c.expn=a.expn+b.expn;
OrderInsertMerge(&Pc,c,cmp);
qb=qb->next;
}
qa=qa->next;
}
DestroyPolyn(Pb);//销毁Pb
ClearList(Pa);//将Pa重置为空表
(*Pa).head=Pc.head;
(*Pa).tail=Pc.tail;
(*Pa).len=Pc.len;
}
//打印输出一元多项式P
voidPrintPolyn(polynomialP)
{
Linkq;
q=P.head->next;//q指向第一个结点
printf("系数指数\n");
while(q)
{
printf("%f%d\n",q->data.coef,q->data.expn);
q=q->next;
}
}
intmain()
{
polynomialp,q;
intm;
//多项式相加
printf("两个一元多项式相加\n");
//构建一个多项式
printf("请输入第一个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(&p,m);
//构建另一个多项式
printf("请输入第二个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(&q,m);
//多项式相加
AddPolyn(&p,&q);
printf("两个一元多项式相加的结果:
\n");
//打印多项式
PrintPolyn(p);
//使用另一种多项式相加的方法
printf("\n两个一元多项式相加(另一种方法)\n");
printf("请输入第三个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(&p,m);
printf("请输入第四个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(&q,m);
//多项式相加的另一种方法
AddPolyn1(&p,&q);
printf("两个一元多项式相加的结果(另一种方法):
\n");
PrintPolyn(p);
//多项式相减
printf("\n两个一元多项式相减\n");
printf("请输入第五个个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(&p,m);
printf("请输入第六个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(&q,m);
//多项式相减
SubtractPolyn(&p,&q);
printf("两个一元多项式相减的结果:
\n");
PrintPolyn(p);
//多项式相乘
printf("\n两个一元多项式相乘\n");
printf("请输入第七个个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(&p,m);
printf("请输入第八个一元多项式的非零项的个数:
");
scanf("%d",&m);
CreatPolyn(&q,m);
//多项式相乘
MultiplyPolyn(&p,&q);
printf("两个一元多项式相乘的结果:
\n");
PrintPolyn(p);
//销毁多项式
DestroyPolyn(&p);
DestroyPolyn(&q);
system("pause");
return0;
}
/*
输出效果:
两个一元多项式相加
请输入第一个一元多项式的非零项的个数:
2
请依次输入2个系数,指数:
(空格)
1011
请输入第二个一元多项式的非零项的个数:
2
请依次输入2个系数,指数:
(空格)
-10-21
两个一元多项式相加的结果:
系数指数
-1.0000001
两个一元多项式相加(另一种方法)
请输入第三个一元多项式的非零项的个数:
2
请依次输入2个系数,指数:
(空格)
1011
请输入第四个一元多项式的非零项的个数:
2
请依次输入2个系数,指数:
(空格)
-10-21
两个一元多项式相加的结果(另一种方法):
系数指数
-1.0000001
两个一元多项式相减
请输入第五个个一元多项式的非零项的个数:
2
请依次输入2个系数,指数:
(空格)
1021
请输入第六个一元多项式的非零项的个数:
2
请依次输入2个系数,指数:
(空格)
-20-11
两个一元多项式相减的结果:
系数指数
3.0000000
3.0000001
两个一元多项式相乘
请输入第七个个一元多项式的非零项的个数:
2
请依次输入2个系数,指数:
(空格)
1011
请输入第八个一元多项式的非零项的个数:
2
请依次输入2个系数,指数:
(空格)
1011
两个一元多项式相乘的结果:
系数指数
1.0000000
2.0000001
1.0000002
请按任意键继续...
*/