单链表-稀疏多项式的表示

版权声明:转载请注明出处。 https://blog.csdn.net/baidu_38304645/article/details/82933191

稀疏多项式:如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;
}

猜你喜欢

转载自blog.csdn.net/baidu_38304645/article/details/82933191
今日推荐