代码改变世界

链表应用——多项式相加

2011-09-24 23:39  gavin's world  阅读(847)  评论(0)    收藏  举报

f(X)=1+x+x2+x5

g(X)=x3+x6+x8+x100

f(X)+g(X)=1+x+x2+x3+x5+x6+x8+x100

两个有序多项式相加合并问题: 

显然第一个想到的是用数组解决,可仔细想一想,数组有诸多弊端,比如大量空间浪费,无法同时存储系数和指数(当然可以用结构体数组,但那不还是链表吗),插入删除都需移动大量数据,索性,就用单链表解决吧

思路如下:

1)将f(X)和g(X)分别存储在两个单向链表内,每个节点存储多项式的一项,内含系数和指数,并指向下一项节点,连贯成一个多项式,头结点分别是head1,和head2;

2)接下来就是两个多项式合并同类项了(初中貌似最喜欢做这玩意了,可计算机可不如你啊),用Node *p1=head->next; 指向f(X)的第一个项节点(head节点均为无数据的表头),

Node *p2=head->next;指向g(X)的的一项; 在定义两个指针pre1=head1、pre2=head2(一会儿有用),准备工作基本做完了。

3)此算法的关键在于将两个有序链表合并成一个,并依然有序;只需将f(X)看成主串,g(X)看成插入串即可,遍历g(X)的各节点,比较其与f(X)各节点指数的大小,小的就插在前面,大的话指针p1就往后移,相等就合并,如果f(X)先遍历到结尾,说明g(X)的其余项都比f(X)的最后一项的指数大,只需将f(X)的最后一个节点指向g(x)的剩余节点即可,最后别忘了把head2删了,因为它是个没有数据的节点。

好了还是上代码吧:

#include<iostream>
using namespace std;

typedef struct node
{
    int coe;     //系数
    int exp;     //指数
    struct node *next;
}Node;
/////////////////////////生成链表
Node *Create()
{
    Node *head=new Node;
    head->next=NULL;
    Node *p=head;
    int n;           //项数
    cout<<"N:";
    cin>>n;
    for(int i=0;i<n;i++)
    {
      p->next=new Node ;
      p=p->next;
      cin>>p->coe>>p->exp;
      p->next=NULL;

    }
    return head;
}

int main()
{
    Node *head1=Create();
    Node *head2=Create();
    Node *p1=head1->next,*p2=head2->next;
    Node *pre1=head1,*pre2=head2;     //pre1指针用来指向比较节点的前一个节点
                                      
//pre2指针用作temp
    while(p1 && p2)
    {
        if(p1->exp < p2->exp)
        {
            pre1=p1;
            p1=p1->next;
        }
        else if(p1->exp > p2->exp)
        {
            pre1->next=p2;
            pre2=p2->next;
            p2->next=p1;
            p2=pre2;
            pre1=pre1->next;
        }
        else if(p1->exp == p2->exp)
        {
            p1->coe+=p2->coe;
            pre2=p2;
            p2=p2->next;
            delete pre2;
        }

    }
    if(p1==NULL)
    {
       pre1->next=p2;
    }
    delete head2;
   Node *temp=head1->next;
   while(temp)
   {
      cout<<temp->coe<<'X'<<'('<<temp->exp<<')'<<" ";
      temp=temp->next;
    }
    return 0;