1. 程式人生 > >單鏈表-稀疏多項式的表示

單鏈表-稀疏多項式的表示

稀疏多項式:如P(x)=1+3x1000+x20000Q(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;
}