在数学上,一个一元多项式可以按照升幂表示为:A(x)=a0+a1x+a2x^2+a3x^3+...+anx^n,它由n+1个系数唯一确定。因此可以用一个线性表(a0,a1,a2...an)来表示,每一项的指数i隐含在系数ai的序号。
若有A(x)=a0+a1x+a2x^2+a3x^3+...+anx^n 和 B(x)=b0+b1x+b2x^2+b3x^3+...+bmx^m,一元多项式求和就是合并同类项的过程。
在实际应用中,多项式的指数可能很高并且变化会很大,在表示多项式的线性表中就会存在很多零元素。一个较好的方法就是只存储非零项,但是需要在存储非零系数的同时存储相应的指数。这样一个一元多项式的每一个非零项可以由其系数和指数唯一确定。
采用顺序表实现两个一元多项式相加的性能不好,采用单链表存储,每一个非零项对应一个结点,且单链表应该递增有序排列。
结点的实现:
struct Elem{
int cef; //系数
int exp; //指数
};
struct Node{
Elem e;
Node *next;
};
设两个工作指针p和q分别指向两个单链表A和B的开始结点。
算法实现:
1.工作指针pre,p,qre,q初始化
2.while(p存在且q存在)执行下列三种情形之一:
2.1如果p->exp小于q->exp,则指针p后移
2.2如果p->exp大于q->exp,则
2.2.1将结点q插入到结点p之前
2.2.2将指针q指向原指结点的下一个结点
2.3如果p->exp等于q->exp,则
2.3.1p->coef=p->coef+q->coef
2.3.2如果p->coef==0,则执行下列操作,否则指针p后移
2.3.2.1删除结点p
2.3.2.2使得指针p指向它原指结点的下一个结点
2.3.3删除结点q
2.3.4使得指针q指向它原指结点的下一个结点
3.如果q不为空,将结点q链接在第一个单链表后面
linklist.h
class LinkList{
friend void Add(LinkList &A, LinkList &B);
private:
Node *first;
public:
LinkList();
LinkList(int a[][MaxSize],int n);
~LinkList();
int Length();
Elem Get(int i);
int Locate(Elem e);
void Insert(int i,Elem em);
Elem Delete(int i);
void PrintList();
void setHead(Node *p);
};
linklist.cpp
void Add(LinkList &A, LinkList &B){
Node *pre = A.first, *p = pre->next;
Node *qre = B.first, *q = qre->next;
while (p != NULL&&q != NULL){
if (p->e.exp > q->e.exp){
Node *v = q->next;
pre->next = q;
q->next = p;
q = v;
}
else if (p->e.exp < q->e.exp){
pre = p;
p = pre->next;
}
else{
p->e.cef += q->e.cef;
if (p->e.cef == 0){
pre->next = p->next;
delete p;
p = pre->next;
}
else{
pre = p;
p = pre->next;
}
qre->next = q->next;
delete q;
q = qre->next;
}
}
if (q != NULL)pre->next = q;
//B.setHead(NULL);
delete B.first;
B.first = NULL;
}
LinkList::LinkList(){
first = new Node;
first->next = NULL;
}
LinkList::LinkList(int a[][MaxSize], int n){
first = new Node;
Node *r = first;
for (int i = 0; i < n; i++){
Node *s = new Node;
s->e.cef = a[0][i];
s->e.exp = a[1][i];
r->next = s;
r = s;
}
r->next = NULL;
}
LinkList::~LinkList(){
while (first != NULL){
Node *p = first;
first = first->next;
delete p;
}
}
Elem LinkList::Get(int i){
Node *p = first->next;
int count = 1;
while (p != NULL&&count < i){
p = p->next;
count++;
}
if (p == NULL)
throw"wrong location!";
else
return p->e;
}
int LinkList::Length(){
int length = 0;
Node *p = first->next;
while (p != NULL){
p = p->next;
length++;
}
return length;
}
int LinkList::Locate(Elem em){
Node *p = first->next;
int count = 1;
while (p != NULL){
if (p->e.cef == em.cef&&p->e.exp == em.exp){
return count;
}
else{
p = p->next;
count++;
}
}
return 0;
}
void LinkList::Insert(int i, Elem em){
Node *p = first;
int count = 1;
while (p != NULL&&count < i){
p = p->next;
count++;
}
if (p == NULL)
throw"wrong location!";
else{
Node *s = new Node;
s->e = em;
s->next = p->next;
p->next = s;
}
}
Elem LinkList::Delete(int i){
Node *p = first;
int count = 1;
while (p != NULL&&count < i){
p = p->next;
count++;
}
if (p == NULL)
throw"wrong location!";
else{
Node *q = p->next;
Elem em = q->e;
p->next = q->next;
delete q;
return em;
}
}
void LinkList::PrintList(){
Node *p = first->next;
while (p != NULL){
cout << p->e.cef << "\t" << p->e.exp << endl;
p = p->next;
}
cout << endl;
}
void LinkList::setHead(Node *p){
first = p;
}
main.cpp
int main(){
int a[2][MaxSize] = {
{1,3,-1,3},
{2,3,4,5}
};
int b[2][MaxSize] = {
{2,-3,2 },
{1,3,4}
};
LinkList A(a, 4);
LinkList B(b, 3);
A.PrintList();
B.PrintList();
Add(A, B);
A.PrintList();
}
测试结果: