一元多项式的表示和相加是数据结构(C语言)中的一个简单的问题,这里我们用C++的一些东西来实现它。(简洁版)
首先是表示多项式,多项式有一些列的单项组成,每一项都有系数和指数两个量,考虑到多项式的长度和指数的不确定性,显而易见,应该使用链表来存储它。
由上面的叙述很容易得到单项的结构:
struct Poly
{
int first;
int second;
Poly *next;
};
first代表单项的常数,second表示指数,next代表下个节点的所在,这个结构体十分的简单。
接下来是多项式的表示,我把它设计为一个类:
class Polynomial
{
public:
Polynomial();
void insert(int ,int); //插入,核心步骤
Polynomial(const Polynomial&);//拷贝构造函数
friend Polynomial operator +(const Polynomial&,const Polynomial&);//重载+运算符
~Polynomial(); //析构函数
void print();//打印多项式
private:
Poly *get_new_poly(int ,int);//得到一个新的单项
Poly *head;链表的头结点
};
当然,这个类的设计有一些问题,这里不做详细的描述,比如我少写了重载赋值运算符。
首先是打印函数的实现:
void Polynomial::print()
{
Poly *p=head->next;
while(p!=NULL)
{
cout<<p->first<<" "<<p->second<<endl;
p=p->next;
}
}
不做太多的描述。
下面是两个构造函数:
Polynomial::Polynomial():head(NULL)
{
head=get_new_poly(0,0);
}
Polynomial::Polynomial(const Polynomial&poly):head(NULL)
{
head=get_new_poly(0,0);
Poly *p=poly.head->next;
while(p!=NULL)
{
this->insert(p->first,p->second);
p=p->next;
}
}
这里我把头结点赋予了一个常数为0,指数为0的单项,这是为了后面算法实现的 方便,无实际意义,也可以看到insert()函数的重要性。
接下来是析构函数和辅助函数,也很简单。
Polynomial::~Polynomial()
{
Poly *p=head;
while(p!=NULL)
{
Poly *pp=p;
p=p->next;
delete pp;
}
}
Poly *Polynomial::get_new_poly(int first,int second)
{
Poly *poly=new Poly;
assert(poly!=NULL);
poly->first=first;
poly->second=second;
poly->next=NULL;
return poly;
}
接下来开始最重要的insert()函数,这个函数完成插入工作,在其中完成自动的排序以及一些其它的工作。
两个多项式相加得到一个新的多项式,就可以看做先把一个多项式插入进新的空的多项式中,然后再把另一个多项式也插入其中,其时间复杂度依旧是O(f(N1)+G(N2)),不变。
void Polynomial::insert(int first,int second)
{
Poly *p_s=head->next,*p_e=head;
while(p_s!=NULL)
{
if(p_s->second == second)
{
p_s->first+=first;
if(p_s->first==0)
{
p_e->next=p_s->next;
delete p_s;
}
return;
}
else if(p_s->second < second )
{
p_e=p_s;
p_s=p_s->next;
}
else
break;
}
Poly *poly=get_new_poly(first,second);
p_e->next=poly;
poly->next=p_s;
}
这个函数中,p_s参与实际的比较和循环,p_e指向的是p_s的前一个节点。
当插入的加点与p_s的指数相同的时候,这个时候不需要新的节点来链接它,只需要常数相加即可,如果结果常数项为0,就删除p_s节点,同时也意味着此次插入完成。
如果p_s的指数项比要插入的项的指数项小,那么更新p_s为链表的下个节点,直到满足条件。
如果p_s的指数项大于要插入的项的指数,那么完成插入操作。
接下来就是重载+操作符的操作:
Polynomial operator +(const Polynomial&poly1,const Polynomial&poly2)
{
Polynomial poly;
Poly *p_head=poly1.head->next;
while(p_head!=NULL)
{
poly.insert(p_head->first,p_head->second);
p_head=p_head->next;
}
p_head=poly2.head->next;
while(p_head!=NULL)
{
poly.insert(p_head->first,p_head->second);
p_head=p_head->next;
}
return poly;
}
分别将两个多项式的每一项插入到新的多项式中。
下面为我写的一个测试代码:
int main()
{
Polynomial poly1,poly2;
poly1.insert(1,1);
poly1.insert(-1,2);
poly2.insert(1,2);
poly2.insert(2,8);
Polynomial poly3=poly1+poly2;
poly3.print();
}
下图为我的测试结果: