1. 实现用freelist 的带头、尾结点的双向链表类的定义,实现双向链表的基本操作。`
a.因为要实现多项式的运算,所以每个结点存储了该项的系 数和该项的指数)
b.带freelist则注意重写他的new和delete方法,并且在外面实例化freelist.
c.在这个实现里还需要注意除了prev(),moveToStart()【移到表头】,moveToEnd()【移到表尾】,moveToFirst()【移到表头的下一个元素】,next()这几个函数能改变curr指针的位置,其余的操作,比如insert(),append(),都是不会改变curr指针的位置的。
#include<iostream>
using namespace std;
template <typename E>
class Link // the node
{
private:
static Link<E>* freelist;
public:
E element; //该项的系数
E ezhinum; //该项的指数
Link* next; //后结点
Link* prev;//前结点
//constructure function
Link(const E itnum, const E itzhi, Link* prevp, Link* nextp)
{
element = itnum;
ezhinum = itzhi;
prev = prevp;
next = nextp;
}
Link(Link* prevp = NULL, Link* nextp = NULL)
{
prev = prevp;
next = nextp;
}
//overloaded "new" operator,
void* operator new(size_t)
{
if (freelist == nullptr)
return ::new Link;
Link<E>* temp = freelist;
freelist = freelist->next;
return temp;
}
//overloaded "delete" opetator
void operator delete(void* ptr)
{
((Link<E>*) ptr)->next = freelist;
freelist = (Link<E>*) ptr;
}
};
//initialize freelist
template <typename E>
Link<E>* Link<E>::freelist = NULL;
template <typename E>
class Doublelist // 双向链表
{
private:
Link<E>* head;
Link<E>* tail; //both tail and head has no element and ezhinum
Link<E>* curr;
int cnt;
void init() //initialization
{
curr = head =new Link<E>;
tail =new Link<E>;
curr->next = tail;
tail->prev = curr;
cnt = 0;
}
void removeall()
{
while (head != NULL)
{
curr = head;
head = head->next;
delete curr;
}
}
public:
Doublelist() //construction
{
init();
}
Doublelist(Doublelist<E>&& L) // copy
{
this->head = L.head;
this->tail = L.tail;
this->curr = L.curr;
this->cnt = L.cnt;
L.head = NULL;
L.tail = NULL;
L.curr = NULL;
L.cnt = 0;
}
~Doublelist()
{
removeall();
}
Doublelist<E>& operator = (Doublelist<E>&& L) //override =
{
this->head = L.head;
this->tail = L.tail;
this->curr = L.curr;
this->cnt = L.cnt;
L.head = NULL;
L.tail = NULL;
L.curr = NULL;
L.cnt = 0;
return *this;
}
void clear()
{
removeall();
init();
}
void insert(const E& itnum, const E& itzhi) //insert a node at curr position
{
curr->next = curr->next->prev = new Link<E>(itnum, itzhi, curr, curr->next);
cnt++;
}
void append(const E& itnum, const E& itzhi) //append a node at the end of the list(before tail)
{
auto newnode = new Link<E>(itnum, itzhi, tail->prev, tail);
tail->prev->next = newnode; // move the next pointer of the node before tail to newnode
tail->prev = newnode; //set the prev pointer of tail to newnode
cnt++; //长度+1
}
E remove()
{
if (curr->next == tail)
return NULL;
E itnum = curr->next->element;
E itzhi = curr->next->ezhinum;
Link<E>* temp = curr->next;
curr->next->next->prev = curr;
curr->next = curr->next->next;
delete temp;
cnt--;
return itnum;
}
E currEle()
{
return curr->element;
}
E currNum()
{
return curr->ezhinum;
}
void changecurr(const E & it)
{
curr->element += it;
}
void prev()
{
if (curr != head)
curr = curr->prev;
}
void moveToStart()
{
curr = head;
}
void moveToFirst() //move to the first actual node
{
curr = head->next;
}
void moveToEnd()
{
curr = tail;
}
void next()
{
if (curr != tail)
curr = curr->next;
}
bool istail()
{
return curr==tail;
}
int length() const
{
return cnt;
}
void print() //print the node's element and elezhinum from the first one to the last one
{
moveToFirst();
cout << cnt << endl;
for(int i=0; i<cnt; i++)
{
cout << curr->element << " " << curr->ezhinum << endl;
curr = curr->next;
}
}
};
2. 实现两个多项式的加法
要求:运算结果得到的链表要求按照指数降序排列的多项式。
思路:用一个新的链表C存储结果,依次比较两个链表A,B,将指数较大且唯一的该项直接加入到C中,该链表curr指针向后移一位;如果指数相同且系数相加不为零,将相加后的结点加入C中,A,B的curr指针均向后移一位。重复上述步骤,直到有一个curr指针指向了链表的tail结点。然后将没有遍历完的那一个链表后面的结点直接加入C中。
Doublelist<int> add(Doublelist<int> &A, Doublelist<int> &B)
{
Doublelist<int> newone;
A.moveToFirst();
B.moveToFirst();
int countA = A.length();
int countB = B.length();
while(true)
{
if(A.currNum() == B.currNum())
{
if(A.currEle()+B.currEle()!=0)
{
newone.append(A.currEle()+B.currEle(),A.currNum());
}
countA--;
countB--;
A.next();
B.next();
}
else if(A.currNum() > B.currNum())
{
newone.append(A.currEle(),A.currNum());
A.next();
countA--;
}
else if(A.currNum() < B.currNum())
{
newone.append(B.currEle(),B.currNum());
B.next();
countB--;
}
if(countA==0 || countB==0)
{
break;
}
}
// find the list that hasn't move to tail and continue
if(countA==0 && countB!=0)
{
while(countB != 0)
{
newone.append(B.currEle(),B.currNum());
B.next();
countB--;
}
}
else if(countB==0 && countA!=0)
{
while(countA != 0)
{
newone.append(A.currEle(),A.currNum());
A.next();
countA--;
}
}
return newone;
};
3.实现两个多项式的乘法
要求:运算结果得到的链表要求按照指数降序排列的多项式。
思路:用一个新的链表C存储结果,以A链表为基准,不断遍历B链表,将B链表结点与当前A链表结点相乘,B链表到达链表尾部后,将其curr指针指回第一个元素,A链表的curr指针向后移一位,直到A链表curr指针到达队尾。在A链表与B链表结点相乘的时候,需要比较新的结点的指数与C链表已有的结点指数的大小,如果比他大就插到他前面,否则就加到他后面。
Doublelist<int> multiple(Doublelist<int> &A, Doublelist<int> &B)
{
Doublelist<int> newone;
A.moveToFirst();
B.moveToFirst();
int countA = A.length();
int countB = B.length();
while(countA!=0)
{
if(countA==A.length())
{
for(int i=0; i<countB; i++)
{
newone.append(A.currEle()*B.currEle(),A.currNum()+B.currNum());
B.next();
newone.next();
}
B.moveToFirst();
}
else
{
for(int i=0; i<countB; i++)
{
int newele = A.currEle() * B.currEle();
int newnum = A.currNum()+ B.currNum();
if(newnum > newone.currNum())
{
newone.prev();
int s = 0;
while(newone.currNum()<newnum)
{
newone.prev();
s++;
}
if(newone.currNum()==newnum)
{
if(newone.currEle()+newele!=0)
{
newone.changecurr(newnum);
}
else
newone.remove();
}
else
{
newone.insert(newele,newnum);
}
for(int i=0; i<s; i++)
{
newone.next();
}
if(countB!=1)
{
B.next();
}
}
else if(newnum == newone.currNum())
{
if(newele + newone.currEle()!=0)
{
newone.changecurr(newele);
newone.next();
}
else
{
newone.remove();
}
if(countB!=1)
{
B.next();
}
}
else
{
newone.append(newele,newnum);
newone.next();
if(countB!=1)
{
B.next();
}
}
}
B.moveToFirst();
}
countA--;
A.next();
}
return newone;
}
4.输入输出示例,main函数
输入格式:
3 2 //第一行,两个正整数分别表示多项式的项数
5 4 //输入第一个多项式各项的系数和指数,按指数降序输入
-3 2
1 0 //第一个多项式:5x4-3x2+1
6 2 //输入第二个多项式各项的系数和指数,按指数降序输入
-3 1 //第二个多项式:6x2-3x
输出格式:
4 //相加得到的多项式的项数
5 4 //每一项的系数与指数,按指数降序排列输出
3 2
-3 1
1 0 //和:5x4+3x2-3x+1
6 //相乘得到的多项式的项数
30 6
-15 5
-13 4
9 3
6 2
-3 1 //乘积:30x6-18x5-13x4+9x3+6x2-3x
main函数
int main()
{
int num1, num2;
cin >> num1 >> num2;
int ele, num;
Doublelist<int> firstone;
Doublelist<int> secondone;
for(int i=0; i<num1; i++)
{
cin >> ele >> num;
firstone.append(ele,num);
}
for(int i=0; i<num2; i++)
{
cin >> ele >> num;
secondone.append(ele,num);
}
Doublelist<int> addlist = add(firstone,secondone);
addlist.print();
Doublelist<int> mullist = multiple(firstone,secondone);
mullist.print();
system("pause");
return 0;
};
这竟然还不关注收藏点赞?!!!
快来一起打败可pia的程序和算法叭!!