您的位置:首页 > 理论基础 > 数据结构算法

数据结构学习之路-第二章:一元多项式的表示及相加

2015-09-04 11:20 330 查看
【 声明:版权所有,转载请标明出处,请勿用于商业用途。 联系信箱:libin493073668@sina.com】

前言:

总算是到了书本中第二章最后的内容了,前面关于链表的相关内容也已经弄得差不多了,现在我们就来学习这章最后的内容,如何用链表来实现一元多项式的表示与相加。对于一元多项式的表现,我们如果使用顺序表的下标存法的话,将会十分简单,但是这对于实际而言的话却并不理想,加入其最高次幂很大,但是项数却很少的话,那样会平白的浪费许多空间,所以我们应该使用链表的存储方式比较理想。

注:

本文仅代表博主本人的一些浅显的见解,欢迎大家评论学习,共同创造出一个良好的环境

对于一些问题,博主会尽量为大家解答,但是如果有疑问没有及时回答的,也希望其他热心人心帮忙解决,鄙人不胜感激

一元多项式的表示与相加

1.存储结构

对于多项式的每一个单元,我们要保存得自然是每个单元得系数与指数了。
typedef struct    //项的表示,多项式的项作为LinkList的数据元素
{
    float coef;   //系数
    int expn;     //指数
} term,ElemType;


2.具体函数与相关实现

my.h包含了一些需要用到的头文件
link.c包含了上一节中我们所介绍的带头结点的链表中除了主函数外所有的函数与定
#include "my.h"
//typedef int ElemType;
typedef int Status;

typedef struct //项的表示,多项式的项作为LinkList的数据元素 { float coef; //系数 int expn; //指数 } term,ElemType;
typedef struct LNode //结点类型
{
ElemType data;
struct LNode *next;
} LNode,*Link,*Position;

typedef struct //链表类型
{
Link head,tail; //分别指向线性链表中的头结点和最后一个结点
int len; //指示线性链表中数据元素的个数
} LinkList;
typedef LinkList polynomial;

#include "link.c"

#define DestroyPolyn DestroyList
#define PolynLength ListLength

Status OrderInsertMerge(LinkList *L,ElemType e,int(* compare)(term,term))
{
//操作结果:按有序判定函数compare()的约定,将值为e的结点插入或合并到升序链表L的适当位置
Position q,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);
}
return OK;
}
else
{
if(MakeNode(&s,e)) //生成该指数项并插入链表
{
InsFirst(L,q,s);
return OK;
}
return ERROR;
}
}

int cmp(term a,term b)
{
//操作结果:依a的指数值<、=或>b的指数值,分别返回-1、0或+1此为升序
if(a.expn==b.expn) return 0;
if(a.expn<b.expn) return -1;
return 1;
}

void CreatPolyn(polynomial *P,int m)
{
//操作结果:输入m项的系数和指数,建立表示一元多项式的有序链表P
Position q,s;
int i;
term e;
InitList(P);
printf("请输入%d个系数,指数:",m);
for(i = 1; i<=m; i++)
{
scanf("%f%d",&e.coef,&e.expn);
if(!LocateElemP(*P,e,&q,cmp)) //当前链表中不存在该指数项,cmp是实参
{
if(MakeNode(&s,e)) //生成结点并插入链表
InsFirst(P,q,s);
}
}
}

void PrintPolyn(polynomial P)
{
//操作结果:打印输出一元多项式P
Link q;
q = P.head->next; //q指向第一个结点
printf("系数 指数\n");
while(q)
{
printf("%f %d\n",q->data.coef,q->data.expn);
q = q->next;
}
}

void AddPolyn(polynomial *Pa,polynomial *Pb)
{
//操作结果:多项式加法:Pa=Pa+Pb,并销毁一元多项式Pb
Position ha,hb,qa,qb;
term a,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: //多项式Pa中当前结点的指数值小
ha = qa;
qa = NextPos(qa); // ha和qa均向后移一个结点
break;
case 0: //两者的指数值相等,修改Pa当前结点的系数值
qa->data.coef+=qb->data.coef;
if(qa->data.coef)
{
ha = qa;
}
else //为0则删除多项式Pa中当前结点
{
DelFirst(Pa,ha,&qa);
FreeNode(&qa);
}
DelFirst(Pb,hb,&qb);
FreeNode(&qb);
qb = NextPos(hb);
qa = NextPos(ha);
break;
case 1: //多项式Pb中当前结点的指数值小
DelFirst(Pb,hb,&qb);
InsFirst(Pa,ha,qb);
qb = NextPos(hb);
ha = ha->next;
}
}
if(!ListEmpty(*Pb))
{
(*Pb).tail = hb;
Append(Pa,qb); //链接Pb中剩余结点
}
DestroyPolyn(Pb); //销毁Pb
}

void AddPolyn1(polynomial *Pa,polynomial *Pb)
{
//操作结果:另一种多项式加法的算法:Pa=Pa+Pb,并销毁一元多项式Pb
Position q;
term b;
q = GetHead(*Pb);
q = q->next;
while(q)
{
b = GetCurElem(q);
OrderInsertMerge(Pa,b,cmp);
q = q->next;
}
DestroyPolyn(Pb);
}

void Opposite(polynomial Pa)
{
//操作结果:一元多项式系数取反
Position q;
q = GetHead(Pa); //qb指向Pb的头结点
q = q->next; //qb指向Pb的第一个结点
while(q)
{
q->data.coef*=-1;
q = q->next;
}
}

void SubtractPolyn(polynomial *Pa,polynomial *Pb)
{
//操作结果:多项式减法:Pa=Pa-Pb,并销毁一元多项式Pb
Opposite(*Pb);
AddPolyn(Pa,Pb);
}

void MultiplyPolyn(polynomial *Pa,polynomial *Pb)
{
//操作结果:多项式乘法:Pa=Pa*Pb,并销毁一元多项式Pb
polynomial Pc;
Position qa,qb;
term a,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);
ClearList(Pa);
(*Pa).head = Pc.head;
(*Pa).tail = Pc.tail;
(*Pa).len = Pc.len;
}

int main()
{
polynomial p,q;
int m;
printf("请输入第一个一元多项式的非零项的个数:");
scanf("%d",&m);
CreatPolyn(&p,m);
printf("请输入第二个一元多项式的非零项的个数:");
scanf("%d",&m);
CreatPolyn(&q,m);
AddPolyn(&p,&q);
printf("两个一元多项式相加的结果:\n");
PrintPolyn(p);
printf("请输入第三个一元多项式的非零项的个数:");
scanf("%d",&m);
CreatPolyn(&q,m);
AddPolyn1(&p,&q);
printf("两个一元多项式相加的结果(另一种方法):\n");
PrintPolyn(p);
printf("请输入第四个一元多项式的非零项的个数:");
scanf("%d",&m);
CreatPolyn(&q,m);
SubtractPolyn(&p,&q);
printf("两个一元多项式相减的结果:\n");
PrintPolyn(p);
printf("请输入第五个一元多项式的非零项的个数:");
scanf("%d",&m);
CreatPolyn(&q,m);
MultiplyPolyn(&p,&q);
printf("两个一元多项式相乘的结果:\n");
PrintPolyn(p);
DestroyPolyn(&p);
return 0;
}


总结:

花了不少的时间温故并总结了第二章线性表的知识,不知道学完之后大家是否已经基本了解了线性表的原理与实现了呢?如果还有没有弄懂的地方,自己更多的去编码实现与调试,编程的学习只有真正动手才能真正的提高自己。那么下一次我们将会正式进入第三章栈与队列的学习之中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: