提示:
1、存儲多項式的數據結構
多項式的通式是pn(x)=anxn+an−1xn−1+...+a1x+a0。n次多項式共有n+1項。直觀地,可以定義一個數組來存儲這n+1個係數。以多項式p(x)=−3.4x10−9.6x8+7.2x2+x爲例,存儲這個多項式的數組如下圖:
可以看出,這種方案適合對某些多項式的處理。但是,在處理一些次數高但項數少的多項式時,存在浪費空間的現象,會有很多閒置的0。
可以使用如下定義的單鏈表結構存儲多項式:鏈表中的每一個結點是多項式中的一項,結點的數據域包括指數和係數兩部分,由指針域連接起多項式中的各項。
typedef struct pnode //定義單鏈表結點類型,保存多項式中的一項,鏈表構成多項式 {
double coef; //係數,浮點數
int exp; //指數,正整數*
struct pnode *next; //指向下一項的指針
} PolyNode;
用於表示多項式的鏈表將如下圖所示,在建立多項式的鏈表時,已經令結點按指數由大到小的順序排列。
2、多項式加法在鏈表存儲結構下的實現
鏈表存儲結構下,多項式加法的實現 在如上定義的單鏈表存儲結構基礎上,討論實現多項式加法的算法。
兩個多項式相加,其規則是對具有相同指數的項,令其係數相加。設兩個待相加的多項式的鏈表的頭指針分別爲head1(第一個多項式)和head2(第二個多項式),兩者的和保存到鏈表head1中。只需要先將head1和head2鏈表的首結點作爲當前結點(分別用p1和p2指向)開始檢測,在遍歷鏈表的過程中,分情況作如下處理:
(1)若兩個多項式中當前結點的指數值相同,則它們的係數相加,結果保存到p1結點,並將p2結點刪除。如果相加後的係數不爲0,p1指向第一個多項式的下一個結點,準備隨後的工作,否則,不保存係數爲0的項,將當前p1結點刪除。
(2)當兩個多項式中對應結點的指數值不相等時,若p1指向的結點的指數大,則p1簡單地指向下一結點即可;而p2指向的結點大時,需要將p2結點插入到p1前,然後p2再重新指回到第二個多項式中的下一結點,繼續進行處理。
(3)檢測過程直到其中的任一個鏈表結束。若p1不爲空,第一個多項式中的剩餘項已經在鏈表中,不作處理,如果p2不爲空,只需要將p2鏈接到相加後的第一個多項式末尾。
上面的討論假設多項式鏈表中,已經按指數由大到小排序,在加法之前,採取多種手段保證這一前提成立。
#include <stdio.h>
#include <malloc.h>
#define MAX 20 //多項式最多項數
typedef struct //定義存放多項式的數組類型
{
double coef; //係數
int exp; //指數
} PolyArray;
typedef struct pnode //定義單鏈表結點類型,保存多項式中的一項,鏈表構成多項式
{
double coef; //係數
int exp; //指數
struct pnode *next;
} PolyNode;
void DispPoly(PolyNode *L) //輸出多項式
{
bool first=true; //first爲true表示是第一項
PolyNode *p=L->next;
while (p!=NULL)
{
if (first)
first=false;
else if (p->coef>0)
printf("+");
if (p->exp==0)
printf("%g",p->coef);
else if (p->exp==1)
printf("%gx",p->coef);
else
printf("%gx^%d",p->coef,p->exp);
p=p->next;
}
printf("\n");
}
void DestroyList(PolyNode *&L) //銷燬單鏈表
{
PolyNode *p=L,*q=p->next;
while (q!=NULL)
{
free(p);
p=q;
q=p->next;
}
free(p);
}
void CreateListR(PolyNode *&L, PolyArray a[], int n) //尾插法建表
{
PolyNode *s,*r;
int i;
L=(PolyNode *)malloc(sizeof(PolyNode)); //創建頭結點
L->next=NULL;
r=L; //r始終指向終端結點,開始時指向頭結點
for (i=0; i<n; i++)
{
s=(PolyNode *)malloc(sizeof(PolyNode));//創建新結點
s->coef=a[i].coef;
s->exp=a[i].exp;
r->next=s; //將*s插入*r之後
r=s;
}
r->next=NULL; //終端結點next域置爲NULL
}
void Sort(PolyNode *&head) //按exp域遞減排序
{
PolyNode *p=head->next,*q,*r;
if (p!=NULL) //若原單鏈表中有一個或以上的數據結點
{
r=p->next; //r保存*p結點後繼結點的指針
p->next=NULL; //構造只含一個數據結點的有序表
p=r;
while (p!=NULL)
{
r=p->next; //r保存*p結點後繼結點的指針
q=head;
while (q->next!=NULL && q->next->exp>p->exp)
q=q->next; //在有序表中找插入*p的前驅結點*q
p->next=q->next; //將*p插入到*q之後
q->next=p;
p=r;
}
}
}
void Add(PolyNode *ha,PolyNode *hb,PolyNode *&hc) //求兩有序集合的並,完成加法
{
PolyNode *pa=ha->next,*pb=hb->next,*s,*tc;
double c;
hc=(PolyNode *)malloc(sizeof(PolyNode)); //創建頭結點
tc=hc;
while (pa!=NULL && pb!=NULL)
{
if (pa->exp>pb->exp)
{
s=(PolyNode *)malloc(sizeof(PolyNode)); //複製結點
s->exp=pa->exp;
s->coef=pa->coef;
tc->next=s;
tc=s;
pa=pa->next;
}
else if (pa->exp<pb->exp)
{
s=(PolyNode *)malloc(sizeof(PolyNode)); //複製結點
s->exp=pb->exp;
s->coef=pb->coef;
tc->next=s;
tc=s;
pb=pb->next;
}
else //pa->exp=pb->exp
{
c=pa->coef+pb->coef;
if (c!=0) //係數之和不爲0時創建新結點
{
s=(PolyNode *)malloc(sizeof(PolyNode)); //複製結點
s->exp=pa->exp;
s->coef=c;
tc->next=s;
tc=s;
}
pa=pa->next;
pb=pb->next;
}
}
if (pb!=NULL) pa=pb; //複製餘下的結點
while (pa!=NULL)
{
s=(PolyNode *)malloc(sizeof(PolyNode)); //複製結點
s->exp=pa->exp;
s->coef=pa->coef;
tc->next=s;
tc=s;
pa=pa->next;
}
tc->next=NULL;
}
int main()
{
PolyNode *ha,*hb,*hc;
PolyArray a[]= {{1.2,0},{2.5,1},{3.2,3},{-2.5,5}};
PolyArray b[]= {{-1.2,0},{2.5,1},{3.2,3},{2.5,5},{5.4,10}};
CreateListR(ha,a,4);
CreateListR(hb,b,5);
printf("原多項式A: ");
DispPoly(ha);
printf("原多項式B: ");
DispPoly(hb);
Sort(ha);
Sort(hb);
printf("有序多項式A: ");
DispPoly(ha);
printf("有序多項式B: ");
DispPoly(hb);
Add(ha,hb,hc);
printf("多項式相加: ");
DispPoly(hc);
DestroyList(ha);
DestroyList(hb);
DestroyList(hc);
return 0;
}