單鏈表-稀疏多項式的表示
阿新 • • 發佈:2018-12-13
稀疏多項式:如P(x)=1+3x1000+x20000; Q(x)=x+x50000
R(x)=1+x+3x1000+x20000+x50000。
數學模型:
P=((1,0),(3,1000),(1,20000)) Q=((1,1),(1,50000)) R=((1,0),(1,1),(3,1000),(1,20000),(1,50000))
一個基礎元素稱為一個小項,可定義型別Term
typedef struct{
float coef;int expn;
}Term;
一個多項式實際可看做元素型別為term的線性結構的資料物件,可線上性表的基礎上實現具體操作。
首先定義輔助巨集:
#define OK 1 #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define NULL 0 #define OVERFLOW -1 typedef int Status;
多項式的儲存結構定義:
//多項式的儲存結構定義
typedef struct{
float coef; //係數
int expn; //指數
}term,ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}*LinkList;
typedef LinkList Polynomial;
插入一個結點,使之按照指數大小從大到小排序。
Status Insert(Polynomial &P,Polynomial &q){ //插入一個結點 if(q->data.coef==0) return OK; LNode *prep,*p; prep=P; p=P->next; while(p&&p->data.expn>q->data.expn){ //有序插入 prep=p; p=p->next; } if(!p) //沒找到插入隊尾 prep->next=q; else{ if(p->data.expn==q->data.expn) { //指數相等 if(p->data.coef==q->data.coef*(-1)){ //係數和為0則銷燬 prep->next=p->next; free(p); } else //否則係數改變 p->data.coef+=q->data.coef; } else{ //指數不相等,插入這一項 prep->next=q; q->next=p; } } return OK; }
輸入n項指數與係數,建立一元多項式.
Status InputElem(ElemType &e){ //輸入一個項 scanf("%f %d",&e.coef,&e.expn); return OK; } Status CreatePolyn(Polynomial &P,int n){ //輸入n項指數與係數,建立一元多項式 printf("請輸入多項式的項數: "); scanf("%d",&n); if(n<0) return ERROR; LNode *p; P=(LNode *)malloc(sizeof(LNode)); if(!P) //建立失敗 exit(OVERFLOW); P->next=NULL; for(int i=0;i<n;i++){ p=(LNode *)malloc(sizeof(LNode)); p->next=NULL; if(!p) exit(OVERFLOW); printf("請輸入第 %d 項的係數與指數 :",i+1); InputElem(p->data); Insert(P,p); //插入這個項,要求冪遞增,乘法等也可用 } }
輸出多項式.
Status PrintPolyn(Polynomial &P){
//輸出多項式
if(!P->next)
printf("空多項式\n");
else{
LNode *p=P->next;
while(p){
if(p->data.coef>0&&p!=P->next)
printf("+");
if(p->data.coef==-1&&p->data.expn!=0)
printf("-");
if(p->data.coef!=1&&p->data.coef!=-1)
printf("%.f",p->data.coef);
else if((p->data.coef==1||p->data.coef==-1)&&p->data.expn==0)
printf("%.f",p->data.coef);
if(p->data.expn!=0)
printf("x");
if(p->data.expn!=1&&p->data.expn!=0)
printf("^%d",p->data.expn);
p=p->next;
}
printf("\n");
}
return OK;
}
銷燬一元多項式.
Status DestroyPolyn(Polynomial &P){
//銷燬一元多項式
LNode *p=P,*q;
while(p){
q=p->next;
free(p);
p=NULL;
p=q;
}
return OK;
}
計算Pa=Pa+Pb 並銷燬Pb。
Status AddPolyn(Polynomial &Pa,Polynomial &Pb){
//計算Pa=Pa+Pb 並銷燬Pb。
//如果pa指數等於pb的指數 一種情況兩者係數和為0,此時
//銷燬pa項並且釋放pb當前項。反之pa係數加上pb的係數並且釋放pb當前項
LNode *pa=Pa->next,*pb=Pb->next;
LNode *prea=Pa,*preb=Pb;
while(pa&&pb) { //用兩個指標遍歷整個連結串列
if(pa->data.expn==pb->data.expn){
if(pa->data.coef==pb->data.coef*(-1)){
prea->next=pa->next;
free(pa);
pa=prea->next;
preb->next=pb->next;
free(pb);
pb=preb->next;
}
else{
pa->data.coef+=pb->data.coef;
prea=pa;
pa=pa->next;
preb->next=pb->next;
free(pb);
pb=preb->next;
}
}
else if(pa->data.expn<pb->data.expn){ //如果pa指數小,將pb這個結點插入pa前面 並且釋放pb當前項
preb->next=pb->next;
pb->next=pa;
prea->next=pb;
pb=preb->next;
}
else { // 比較當前兩項 如果pa指數大 pa後移一位
prea=pa;
pa=pa->next;
}
}
if(pb)
prea->next=pb;
free(Pb);
Pb = NULL;
return OK;
}
計算Pa=Pa-Pb 並銷燬Pb。
Status DecreasePolyn(Polynomial &Pa,Polynomial &Pb){
//計算Pa=Pa-Pb 並銷燬Pb。
LNode *pa=Pa->next,*pb=Pb->next,*q;
LNode *prea=Pa,*preb=Pb;
while(pa&&pb){//用兩個指標遍歷整個連結串列
if(pa->data.expn==pb->data.expn){//如果pa指數等於pb的指數 一種情況兩者係數相等,此時銷燬pa項並且釋放pb當前項。反之pa係數加上pb的係數並且釋放pb當前項
if(pa->data.coef==pb->data.coef) {
prea->next=pa->next;
free(pa);
pa=prea->next;
preb->next=pb->next;
free(pb);
pb=preb->next;
}
else{
pa->data.coef-=pb->data.coef;
prea=pa;
pa=pa->next;
preb->next=pb->next;
free(pb);
pb=preb->next;
}
}
else if(pa->data.expn<pb->data.expn){//如果pa指數小,將pb這個結點插入pa前面 並且釋放pb當前項
pb->data.coef*=(-1);
preb->next=pb->next;
pb->next=pa;
prea->next=pb;
pb=preb->next;
}
else{//比較當前兩項 如果pa指數大 pa後移一位
prea=pa;
pa=pa->next;
}
}
q=pb;
while(pb){
pb->data.coef*=(-1);
pb=pb->next;
}
if(q)
prea->next=q;
free(Pb);
return OK;
}
計算Pc=Pa*Pb 。
Status RidePolyn(Polynomial &Pa,Polynomial &Pb,Polynomial &Pc){
//計算Pc=Pa*Pb 。
Pc=(LNode *)malloc(sizeof(LNode));
if(!Pc)
exit(OVERFLOW);
Pc->next=NULL;
LNode *pa=Pa->next,*pb=Pb->next,*p; //設兩個指標遍歷Pa Pb
while(pa) { //迴圈Pa與Pb 將每一項相乘,得到一個新的結點插入Pc中
while(pb) {
p=(LNode *)malloc(sizeof(LNode)); //設立一個新結點
p->next=NULL;
if(!p)
exit(OVERFLOW);
p->data.coef=pa->data.coef*pb->data.coef;
p->data.expn=pa->data.expn+pb->data.expn;
Insert(Pc,p);//插入新結點
pb=pb->next;
}
pa=pa->next;
pb=Pb->next;
}
return OK;
}
計算Pc=Pa/Pb 。商存入Pc,餘數存入Pa.
Status RemovePolyn(Polynomial &Pa,Polynomial &Pb,Polynomial &Pc){
//計算Pc=Pa/Pb 。商存入Pc,餘數存入Pa
//演算法思路:首先整除一下,然後計算得到的餘數,然後再用餘數除Pb,
//不斷迴圈直到餘數的首項指數小於Pb的首項指數為止,即餘數為0
Polynomial P; //設立一個臨時多項式
Pc=(LNode *)malloc(sizeof(LNode));
if(!Pc)
exit(OVERFLOW);
Pc->next=NULL;
float a;
int b;
LNode *pa=Pa->next,*pb=Pb->next,*p,*q;
while(pa&&pb&&pa->data.expn>=pb->data.expn){ //當Pa首項的指數大於等於Pb首項的指數
p=(LNode *)malloc(sizeof(LNode)); //設立新節點儲存Pa與Pb首項之商
if(!p)
exit(OVERFLOW);
p->next=NULL;
a=pa->data.coef/pb->data.coef;
b=pa->data.expn-pb->data.expn;
p->data.coef=a;
p->data.expn=b;
Insert(Pc,p); //將得到的商結點插入Pc中
P=(LNode *)malloc(sizeof(LNode)); //建立臨時多項式
if(!P)
exit(OVERFLOW);
P->next=NULL;
while(pb) {//遍歷Pb中的每一項
q=(LNode *)malloc(sizeof(LNode)); //設立新節點,儲存pb中項與得到的商結點相乘的項
if(!q)
exit(OVERFLOW);
q->next=NULL;
q->data.coef=a*pb->data.coef;
q->data.expn=b+pb->data.expn;
Insert(P,q); //將得到結點插入臨時多項式中
pb=pb->next;
}
DecreasePolyn(Pa,P);//將Pa與臨時多項式相減 得到一個新的Pa
pa=Pa->next; //獲得首項
pb=Pb->next;
}
return OK;
}
進行多項式的求導.
Status PolynDerivative(Polynomial &P){
//進行多項式的求導
LNode *p=P->next,*prep=P;
while(p){ //遍歷每一個項
if(p->data.expn==0){//若指數為零,刪除這個項
prep->next=p->next;
free(p);
p=prep->next;
}
else{ //指數不為零 修改係數與指數
p->data.coef*=p->data.expn;
p->data.expn--;
prep=p;
p=p->next;
}
}
return OK;
}