数据结构已经节课。和大家分享一下我自己的代码。http://download.youkuaiyun.com/detail/u011253734/7665207上面有
多项式运算类的头文件
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include<iostream>
#include<cstdio>
using namespace std;
struct LinkNode{
int coef;
int exp;
LinkNode* link;
LinkNode(LinkNode *ptr=NULL){link=ptr;}
LinkNode(const int & item1,const int & item2):coef(item1),exp(item2){}
friend ostream& operator<<(ostream&,LinkNode& );
};
class Cpolynomal
{ friend ostream& operator<<(ostream&, Cpolynomal&);//重载各种运算符
friend istream& operator>>(istream&,Cpolynomal&);
friend Cpolynomal operator + ( Cpolynomal&, Cpolynomal&);
friend Cpolynomal operator - ( Cpolynomal&, Cpolynomal&);
friend Cpolynomal operator * ( Cpolynomal&, Cpolynomal&);
friend bool operator == (Cpolynomal&,Cpolynomal&);
friend bool operator != (Cpolynomal&,Cpolynomal&);
friend void value(Cpolynomal&,int);//求值
public:
Cpolynomal operator+=(Cpolynomal&);
Cpolynomal operator-=(Cpolynomal&);
Cpolynomal operator*=(Cpolynomal&);
void derivation();//求导
void multiplication( Cpolynomal h1, Cpolynomal h2);
Cpolynomal(){first=new LinkNode(0,0);use=new size_t(1);}
Cpolynomal(const int & item1,const int & item2){first = new LinkNode(item1,item2);}
LinkNode * GetHead(){return first;}
Cpolynomal(const Cpolynomal& obj):first(obj.first),use(obj.use){++*use;}
Cpolynomal&operator=(const Cpolynomal&);
~Cpolynomal(){if(--*use==0){makeEmpty();}}
void makeEmpty();
void input();
void output();
void remove_0();
int max_exp();
bool all_zero();
friend Cpolynomal operator-(Cpolynomal&);
private:
LinkNode *first;
size_t *use;
};
#endif
以下是实现文件。
use的作用是在于延迟析构。你可以看重载乘法的友元函数,自己思考思考他的作用。我会在最后解释。
#include"polynomial.h"
Cpolynomal&Cpolynomal::operator=(const Cpolynomal&rhs)
{++*rhs.use;
if(--*use==0){makeEmpty();}
first=rhs.first;
use=rhs.use;
return * this;
}
void value( Cpolynomal& a, int n)
{ int val=0;
int mid;
LinkNode* ptr=a.GetHead()->link;
while(ptr!=NULL)
{ mid=1;
for(int i=0;i<ptr->exp;i++)
mid=mid*n;
val=val+ptr->coef*mid;
ptr=ptr->link;
}
cout<<"f("<<n<<")="<<val<<endl;
}
void Cpolynomal::derivation()
{
LinkNode* ptr=first;
ptr=ptr->link;
while(ptr!=NULL)
{ptr->coef=ptr->coef*ptr->exp;
ptr->exp=ptr->exp-1;
ptr=ptr->link;}
}
bool Cpolynomal::all_zero()
{ LinkNode *ptr=first;
bool a=true;
while(ptr!=NULL)
{if(ptr->coef!=0)a=false;
ptr=ptr->link;
}
return a;
}
int Cpolynomal::max_exp()
{int max;
LinkNode* p1=first;
while(p1!=NULL)
{
max=p1->exp;
p1=p1->link;
}
return max;
}
istream& operator>>(istream& is,Cpolynomal& h1)
{ int flag, sign, sum, x;
char c;
LinkNode * p =h1.first;
while ( (c=getchar()) !='\n' )
{
if ( c == '<' )
{ sum = 0;
sign = 1;
flag = 1;
}
else if ( c =='-' )
sign = -1;
else if( c >='0'&& c <='9' )
{ sum = sum*10 + c - '0';
}
else if ( c == ',' )
{ if ( flag == 1 )
{ x = sign * sum;
sum = 0;
flag = 2;
sign = 1;
}
}
else if ( c == '>' )
{ p->link = new LinkNode();
p->link->coef = x;
p->link->exp = sign * sum;
p = p->link;
p->link = NULL;
flag = 0;
}
}
return is;
}
bool operator == ( Cpolynomal& h1, Cpolynomal& h2)
{
Cpolynomal c;
c=h1-h2;
return c.all_zero();
}
bool operator != ( Cpolynomal& h1, Cpolynomal& h2)
{
return !(h1==h2);
}
Cpolynomal operator-(Cpolynomal&h1)
{LinkNode* p1=h1.first;
int max;
Cpolynomal c;
LinkNode* p3=c.GetHead();
int i;
max=h1.max_exp();
for(i=0;i<=max;i++)
{
p3->link=new LinkNode();
p3=p3->link;
p3->coef=0;
p3->exp=i;
p3->link=NULL;
}
for(p1=h1.GetHead()->link;p1!=NULL;p1=p1->link)
{
for(p3=c.GetHead()->link;p3!=NULL;p3=p3->link)
{
if(p3->exp==p1->exp)
{p3->coef=-p1->coef;break;}
}
}
return c;
}
ostream& operator<<(ostream &os, Cpolynomal& a)
{ if(a.all_zero()) {cout<<0;return os;}
LinkNode* ptr=a.GetHead();
ptr=ptr->link;
bool i=true;
while(ptr!=NULL)
{
if(ptr->coef!=0)
{
if(ptr->coef>0)
{if(i) {os<<ptr->coef<<"x^"<<ptr->exp;i=false;}
else os<<'+'<<ptr->coef<<"x^"<<ptr->exp;
}
else{i=false;os<<ptr->coef<<"x^"<<ptr->exp;
}}
ptr=ptr->link;
}
return os;
}
Cpolynomal operator + (Cpolynomal& h1,Cpolynomal& h2)
{ LinkNode* p1=h1.first;
LinkNode* p2=h2.first;
int max;
Cpolynomal c;
LinkNode* p3=c.GetHead();
int i;
max=h1.max_exp()>h2.max_exp()? h1.max_exp():h2.max_exp();
for(i=0;i<=max;i++)
{
p3->link=new LinkNode();
p3=p3->link;
p3->coef=0;
p3->exp=i;
p3->link=NULL;
}
for(p1=h1.GetHead()->link;p1!=NULL;p1=p1->link)
{
for(p3=c.GetHead()->link;p3!=NULL;p3=p3->link)
{
if(p3->exp==p1->exp)
{p3->coef=p3->coef+p1->coef;break;}
}
}
int coef,exp;
for(p2=h2.GetHead()->link;p2!=NULL;p2=p2->link)
{ for(p3=c.GetHead()->link;p3!=NULL;p3=p3->link)
{
if(p3->exp==p2->exp)
{p3->coef=p3->coef+p2->coef;break;}
}
}
return c;
}
Cpolynomal operator - (Cpolynomal& h1,Cpolynomal& h2)
{
Cpolynomal c;
c=-h2;
c=h1+c;
return c;
}
Cpolynomal operator * (Cpolynomal& h1, Cpolynomal& h2)
{ Cpolynomal c;
LinkNode* p1=h1.GetHead();
LinkNode* p2=h2.GetHead();
int max1,max2;
while(p1!=NULL)
{
max1=p1->exp;
p1=p1->link;
}
while(p2!=NULL)
{
max2=p2->exp;
p2=p2->link;
}
max1=max1+max2;
LinkNode* p3=c.first;
int i;
for(i=0;i<=max1;i++)
{
p3->link=new LinkNode(0,i);
p3=p3->link;
p3->coef=0;
p3->exp=i;
p3->link=NULL;
}
int coef,exp;
for(p1=h1.GetHead()->link;p1!=NULL;p1=p1->link)
for(p2=h2.GetHead()->link;p2!=NULL;p2=p2->link)
{ coef=p2->coef*(p1->coef);
exp=p2->exp+p1->exp;
for(p3=c.first->link;p3!=NULL;p3=p3->link)
{
if(p3->exp==exp)
{p3->coef=p3->coef+coef;break;}
}
}
return c;
}
Cpolynomal Cpolynomal::operator +=( Cpolynomal&h1)
{ Cpolynomal c;
c=*this;
c=c+h1;
return c;
}
Cpolynomal Cpolynomal::operator -=( Cpolynomal&h1)
{
*this=*this-h1;
return *this;
}
Cpolynomal Cpolynomal::operator *=( Cpolynomal&h1)
{
*this=*this*h1;
return *this;
}
void Cpolynomal::makeEmpty()
{ LinkNode* q;
while(first->link!=NULL)
{
q=first->link;
first->link=q->link;
delete q;
}
delete use;
}
我单独把这个重载乘法函数拿出来看
Cpolynomal operator * (Cpolynomal& h1, Cpolynomal& h2)
{ Cpolynomal c;//临时变量c
LinkNode* p1=h1.GetHead();
LinkNode* p2=h2.GetHead();
int max1,max2;
while(p1!=NULL)
{
max1=p1->exp;
p1=p1->link;
}
while(p2!=NULL)
{
max2=p2->exp;
p2=p2->link;
}
max1=max1+max2;
LinkNode* p3=c.first;
int i;
for(i=0;i<=max1;i++)
{
p3->link=new LinkNode(0,i);
p3=p3->link;
p3->coef=0;
p3->exp=i;
p3->link=NULL;
}
int coef,exp;
for(p1=h1.GetHead()->link;p1!=NULL;p1=p1->link)
for(p2=h2.GetHead()->link;p2!=NULL;p2=p2->link)
{ coef=p2->coef*(p1->coef);
exp=p2->exp+p1->exp;
for(p3=c.first->link;p3!=NULL;p3=p3->link)
{
if(p3->exp==exp)
{p3->coef=p3->coef+coef;break;}
}
}
return c;//一系列操作后返回c,如果没有引用计数的话,c会拷贝给左值,然后自身析构函数,可想而知他会把他所连着的所有指针地址销毁,实际上返回的不指向任何东西
}
这时候引用计数就有用了。
use是指针,是为了共享use。
在构造函数中默认分配地址,并且赋其地址上的值为1。
拷贝构造的时候 拷贝地址,并且加一。
重载赋值运算符的时候,左操作数引用计数减一,右操作数的加一
析构函数则调用时减一,如果其值为0,说明只有一个变量在用,就直接析构。
有什么不对的地方还请大家指教。。