多项式ADT:
设一元整系数多项式:
每一项多项式的形式是coef*x^exp,coef为该项的系数,exp是变元x的指数。
我们将一个多项式看成是一个线性表,线性表的元素就是多项式的项,下面采用一种带表头的单循环链表表示多项式。
多项式的项是系数coef和指数exp的偶对,这样多项式的项可表示为Term=<coef,exp>
typedef struct term
{
int Cofe,Exp;
}Term;
typedef Term T;
typedef struct node
{
T Element;
struct node* Link;
}Node;
//现在每个结点有三部分信息:Coef,Exp,Link。约定降幂排列,表头的Exp=-1.
//多项式数据类型Ploynomial定义为:
typedef struct polynomial
{
Node* First;
}Polynomial;
建立空多项式并初始化:
void CreatePolynomial(Polynomial* list)
{
T x;
x.Coef = 0;
x.Exp = -1;
list->First = NewNode2(x);
list->First->Link = list->First;//结点指向自身
}
多项式的项的输入和输出函数:
T* InputElement()
{
static T a;
printf("\nEnter a term(Coef,Exp)\n");
scanf("%d %d",&a.Coef,&a.Exp);
return &a;
}
void PrintElement(T x)
{
if(x.Coef != 0)
{
printf("%d",x.Coef);
switch(x.Exp)
{
case 0:break;
case 1:printf("X");break;
default:printf("X^%d",x.Exp);break;
}
}
}
增加项函数
void AddTerms(Polynomial* list)
{
char c;
Node* p,*q=list->First;
printf("\nAdd a term into a polynomial.\n");
printf("\nAnother term?y/n");
while((c = getchar()) == '\n');
while(tolower(c)!='n')
{
p = NewNode1();
p->Link = q->Link;
q->Link = p;
q = p;//临时指针指向下一个结点,为循环创造条件。
printf("Another term?y/n");
while((c=getchar())=='\n');
}
}
打印多项式:
void PrintPolynomial(Polynomial list)
{
BOOL IsFirst = TRUE;
Node* p = list->First->Link;//因为第一个结点为空表头,因此指向第二个结点
printf("\nThe Ploynomial is: \n");
for(;p!=list.First;p = p->Link)
{
if(!IsFirst && p->Element.Coef>0)//如果不是表头并且系数不为0要手动输出加号
printf("+");//输出“+”
IsFirst = FALSE;//防止开头输出+号
PrintElement(p->Element);
}
printf("\n");
}
多项式相加
多项式q(x) = q(x)+p(x),设指针p,q分别指向多项式p(x)和q(x)当前正在比较的项,指针P1指向*q的前驱结点。
若此时指针q指向的项正在与p指向的项比较。若p指向的项的幂数大于q指向的项的幂数,则复制此时p指向的项插入在q1指针之后。q1移到新项,q不动,p后移一项。
若p指向的项的幂数等于q指向的项的幂数,则将两项系数相加,将合并的项插入在P1后一项,p1后移当新项,q,p均向后移动一项。
若p指向的项的幂数小于q指向的项的幂数,则将q指向的当前想保存在结果项q(x),q,q1向后移一项,p不动。
则具体描述如下:
int exp_comp(T x,T y)//该函数比较两个项的指数的大小
{
if(x.Exp == y.Exp)
return 0;
else if(x.Exp > y.Exp)
return 1;
else
return -1;
}
void PopAdd(Polynomial A,Polynomial* B)//相加多项式A和B
{
Node* q,*q1,*p,T x;
p = A.First->Link;q = B.First->Link;
q1 = q->Link;
while(p->Element.Exp >= 0)//如果幂数小于0的话,则表示处理结束,因为为循环列表,表头幂数为-1
{
switch(exp_comp(p>Element,q->Element))//比较对应项幂数
{
case -1:
q1 = q;q = q->Link;break;
case 0;
q->Element.Coef = q->Element.Coef + p->Element.Coef;
if(q->Element.Coef == 0)//若相加后两项抵消
{
q2 = q; //将临时结点指针指向q,为下面的删除作准备
q1 = q->Link;//q1指向q的后一项。即删除结点q之后,q1向后移一项
q = q->Link;//q向后移一项
free(q2);//删除结点
p = p->Link;
}
else
{
q1 = q; //直接向后移指针,因为前面已经改变了q多项式项的系数
q = q->Link;
p = p->Link;
}
break;
case 1:
x.Coef = p->Element.Coef;//复制数据
x.Exp = P->Element.Exp;
q2 = NewNode2(x);//新建结点
q2->Link = q;//新结点插在p1后面
q1->Link = q2;//q1向后移一项
q1 = q2;
}
}
}