2007.08.25一元多项式的表示及相加

一元多项式的表示及相加
对于符号多项式的各种操作,实际上都可以利用线性表来处理。比较典型的是关于一元多项式的处理。在数学上,一个一元多项式P n(x)可按升幂的形式写成:Pn(x)=p 0+p 1x+p 2x 2+p 3x 3+…+p nx n。它实际上可以由n+1个系数唯一确定。因此,在计算机内,可以用一个线性表P来表示:P=(p 0,p 1,p 2,…,p n)其中每一项的指数隐含在其系数的序号里了。
假设Q m(x)是一个一元多项式,则它也可以用一个线性表Q来表示,即Q=(q 0,q 1,q 2,…,q n)若假设m<n,则两个多项式相加的结果R n(x)=P n(x)+Q m(x),也可以用线性表R来表示:R(p 0+q 0,p 1+q 1,p 2+q 2,,p m+q m,p m+1,…,p n)。
我们可以采用顺序表存储结构来实现顺序表的方法,使得多项式的相加的算法定义十分简单,即p[0]存系数p 0,p[1]存系数p 1,…,p[n]存系数p n,对应单元的内容相加即可。但是在通常的应用中,多项式的指数有时可能会很高并且变化很大。例如:R(x)=1+5x 10000+7x 20000
若采用顺序存储,则需要20001个空间,而存储的有用数据只有三个,这无疑是一种浪费。若只存储非零系数项,则必须存储相应的指数信息才行。
假设一元多项式P n(x)=p 1x e1+p 2x e2+…+p mx em,其中p ie i的项的系数(且0≤e 1≤e 2≤…≤e m=n),若只存在非零系数,则多项式中每一项有两项构成(指数项和系数项),用线性表来表示,即((p 1,e 1),(p 2,e 2),…,(p m,e m))。
采用这样的方法存储,在最坏情况下,即n+1个系数都不为零,则比只存储系数的方法多存储1倍的数据。但对于非零系数多的多项式则不宜采用这种表示。
对与线性表的两种存储结构,一元多项式也有存储表示方法。在实际应用中,可以是具体情况而定。下面将学习到用单链表实现一元多项式相加运算的方法。
(1)用单链表存储多项式的结点结构如下:

typedef struct Polynode
{
 int coef;
 int exp;
 struct Polynode *next;
}Polynoce,*Polylist;

(2)通过键盘输入一组多项式的系数和指针,以输入系数0为结束标志,并约定建立多项式链表时,总是按指数从大到小的顺序排列。
算法描述:从键盘接受输入的系数和指针;用尾插法建立一元多项式的链表。

Polylist polycreate()
{
 Polynode *head,*rear,8s;
 int c,e;
 head=(Polynode *)malloc(sizeof(Polynode));/*建立多项式的头结点*/
 rear=head;/*rear始终指向单链表的尾,便于尾插法建表*/
 scanf("%d,%d",&c,&e);/*键入多项式的系数和指针项*/
 while(c!=0)/*若c=0,则代表多项式的输入结束*/
   {
    s=(Polynode *)malloc(sizeof(Polynode));/*申请新的结点*/
    s->coef=c;
    s->exp=e;
    rear->next=s;/*在当前表尾做插入*/
    rear=s;
    scanf("%d,%d",&c,&e);
   }
 rear-next=NULL;/*将表的最后一个结点的nest置NULL,以示结束*/
 return (head);
}
算法        用尾插法建立一元多项式的链表

图2.19所示为两个多项式的单链表,分别表示多项式A(x)=7+3x+9x 8+5x 17和多项式B(x)=8x+22x 7-9x 8
多项式相加的运算规则是:两个多项式中所有指数相同的项的对应系数相加,若和不为零,则构成“和多项式”中的一项;所有指数不相同的项均复抄到“和多项式”中。以单链表作为存储结构,并且“和多项式”中的结点无需 生成,则可看成是将多项式B加到多项式A中,由此的到下列运算规则(设p、q分别指向多项式A、B的一项,比较结点的指数项):
若p->exp<q->exp,则结点p所指的结点应是“和多项式”中的一项,令指针p后移;
若p->exp>q->exp,则结点q所指的结点应是“和多项式”中的一项,将结点q插入在结点p之前,且令指针q在原来的链表上后移;
若p->exp=q->exp,则将两个结点中的系数相加,当和不为零时修改结点p的系数域,释放q结点;若和为零,则和多项式中无此项,从A中删去p结点,同时释放p和q结点。

void polyadd(Polylist polya;Polylist polyb)
/*此函数用于将两个多项式相加,然后将和多项式存放在多项式polya中,并将多项式ployb删除*/
{
 Polynode *p,*q,*pre,*temp;
 int sum;
 p=polya->next;/*令p和qfenbie指向polya和polyb多项式链表中的第一个结点*/
 q=polyb->next;
 pre=polya;/*pre指向和多项式的尾结点*/
 while(p!=NULL&&q!=NULL)/*当两个多项式均为扫描结束时*/
   {
    if(p->exp<q->exp)
      /*如果p指向的多项式项的指数小于q的指数,将p结点加入到和多项式中*/
       {
        pre-next=p;pre=pre->next;
        p=p->next;
       }
    else if(p->exp==q->exp)/*若指数相等,则相应的系数相加*/
            {
             sum=p->coef+q->coef;
             if(sum!=0)
                {
                 p->coef=sum;
                 pre->next=p;pre=pre->next;
                 p=p-next;temp=q;q=q->next;free(temp);
                }
             else
                {
                 temp=p->next;free(p);p=temp;
                 /*若系数和为零,则删除结点p与q,并将指针指向下一个结点*/
                 temp=q->next;free(q);q=temp;
                }
            }
         else
            {
             pre->next=q;pre=pre->next;/*将q结点加入到和多项式中*/
             q=q->next;
            }
   }
 if(p!=NULL)/*多项式A中还有剩余,则将剩余的结点加入到和多项式中*/
    pre->next=p;
 else/*否则,将B中的结点加入到和多项式中*/
    pre->next=q;
}
算法        多项式相加

假设A多项式有M项,B多项式有N项,则上述算法的时间复杂度为O(M+N)。
图2.20所示为图2.19中两个多项式的和,其中孤立的结点代表被释放的结点。
通过对多项式加法的介绍,我们可以将其推广到实现两个多项式的相乘,因为乘法可以分解为一系列的加法运算。
 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言链表是通过指针实现的数据结构,每个节点包含一个数据元素和一个指向下一个节点的指针。链表可以用于存储任意类型的数据结构,包括一元多项式。 在用单链表存储一元多项式时,每个节点可以表示一个项,包含两个元素:系数和指数。链表的头节点可以表示多项式本身,包含一个指向第一个项的指针。 实现一元多项式计算时,可以通过遍历链表,将相同次数的项合并,得到新的多项式。具体实现可以使用循环或递归算法,遍历链表并进行计算。 以下是一个简单的单链表实现一元多项式计算的示例代码: ```c #include <stdio.h> #include <stdlib.h> // 定义一元多项式项的结构体 typedef struct node { float coef; // 系数 int exp; // 指数 struct node* next; // 指向下一个节点的指针 } Term; // 定义一元多项式的结构体 typedef struct { Term* head; // 指向第一个项的指针 } Polynomial; // 创建一元多项式 Polynomial create_polynomial() { Polynomial poly; poly.head = NULL; return poly; } // 在一元多项式中插入一项 void insert_term(Polynomial* poly, float coef, int exp) { Term* term = (Term*)malloc(sizeof(Term)); term->coef = coef; term->exp = exp; term->next = NULL; if (poly->head == NULL) { poly->head = term; } else { Term* p = poly->head; while (p->next != NULL) { p = p->next; } p->next = term; } } // 遍历一元多项式并打印 void print_polynomial(Polynomial poly) { Term* p = poly.head; while (p != NULL) { printf("%.2fx^%d ", p->coef, p->exp); if (p->next != NULL) { printf("+ "); } p = p->next; } printf("\n"); } // 计算一元多项式的值 float evaluate_polynomial(Polynomial poly, float x) { float result = 0; Term* p = poly.head; while (p != NULL) { result += p->coef * pow(x, p->exp); p = p->next; } return result; } // 合并一元多项式 Polynomial merge_polynomial(Polynomial poly1, Polynomial poly2) { Polynomial result = create_polynomial(); Term *p1 = poly1.head, *p2 = poly2.head; while (p1 != NULL && p2 != NULL) { if (p1->exp > p2->exp) { insert_term(&result, p1->coef, p1->exp); p1 = p1->next; } else if (p1->exp < p2->exp) { insert_term(&result, p2->coef, p2->exp); p2 = p2->next; } else { insert_term(&result, p1->coef + p2->coef, p1->exp); p1 = p1->next; p2 = p2->next; } } while (p1 != NULL) { insert_term(&result, p1->coef, p1->exp); p1 = p1->next; } while (p2 != NULL) { insert_term(&result, p2->coef, p2->exp); p2 = p2->next; } return result; } int main() { Polynomial poly1 = create_polynomial(); insert_term(&poly1, 2, 3); insert_term(&poly1, -3, 2); insert_term(&poly1, 1, 0); printf("Poly1: "); print_polynomial(poly1); Polynomial poly2 = create_polynomial(); insert_term(&poly2, -4, 3); insert_term(&poly2, 3, 1); insert_term(&poly2, 2, 0); printf("Poly2: "); print_polynomial(poly2); Polynomial poly3 = merge_polynomial(poly1, poly2); printf("Poly3: "); print_polynomial(poly3); float result = evaluate_polynomial(poly3, 2); printf("Result: %.2f\n", result); return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值