题目来源:
C语言链表实现
乘法的大体思路是利用加法将每次相乘得到的多项式相加。
加法的大体思路是每次遍历将幂数大的项添加在链表末尾。
链表的第一个节点不存储数据。
定义尾节点,方便插入新的节点。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int c;
int e;
struct Node *next;
} LinkList;
int n1;
int n2;
LinkList *head1;
LinkList *head2;
LinkList *head3;//多项式乘法
LinkList *head4;//多项式加法
LinkList* clearList(LinkList* list)
{
LinkList *t;
LinkList *p;
t=list->next;
while(t)
{
p=t;
t=t->next;
free(p);
}
return list;
}
LinkList* addNode(int cc,int ee,LinkList* end)//添加节点
{
LinkList *t;
t=(LinkList*)malloc(sizeof(LinkList));
t->c=cc;
t->e=ee;
end->next=t;
end=t;
return end;
}
LinkList* creatList(int n)//创建链表
{
LinkList *head;//头指针,不存储数据
LinkList *end;
head=(LinkList*)malloc(sizeof(LinkList));
head->next=NULL;
end=head;
LinkList *node=NULL;
for(int i=0; i<n; i++)
{
node=(LinkList*)malloc(sizeof(LinkList));
scanf("%d%d",&node->c,&node->e);
end->next=node;
end=node;
}
end->next=NULL;
return head;
}
LinkList* addList(LinkList* list1,LinkList* list2)//链表相加
{
LinkList *p1,*p2;
LinkList *head;//头指针,不存储数据
LinkList *end;
int c;
p1=list1->next;
p2=list2->next;
head=(LinkList*)malloc(sizeof(LinkList));
head->next=NULL;
end=head;
while(p1 && p2)
{
if(p1->e > p2->e)
{
end=addNode(p1->c,p1->e,end);
p1=p1->next;
}
else if(p1->e < p2->e)
{
end=addNode(p2->c,p2->e,end);
p2=p2->next;
}
else
{
c=p1->c + p2->c;
if(c!=0)
{
end=addNode(c,p1->e,end);
}
p1=p1->next;
p2=p2->next;
}
}
while(p1)
{
end=addNode(p1->c,p1->e,end);
p1=p1->next;
}
while(p2)
{
end=addNode(p2->c,p2->e,end);
p2=p2->next;
}
end->next=NULL;
return head;
}
LinkList* multiList(LinkList* list1,LinkList *list2)//链表相乘
{
int c,e;
LinkList *head,*end;
LinkList *p1=list1->next;
LinkList *p2=list2->next;
LinkList *thead,*tend;
head=(LinkList*)malloc(sizeof(LinkList));
thead=(LinkList*)malloc(sizeof(LinkList));
head->next=NULL;
thead->next=NULL;
end=head;
tend=thead;
while(p1 && p2)
{
while(p2)
{
c=p1->c * p2->c;
e=p1->e + p2->e;
if(c!=0)
{
tend=addNode(c,e,tend);
}
p2=p2->next;
}
tend->next=NULL;
head=addList(head,thead);
thead=clearList(thead);
tend=thead;
p1=p1->next;
p2=list2->next;
}
free(thead);
end->next=NULL;
return head;
}
void printList(LinkList *head)//输出链表
{
LinkList *p;
p=head->next;
if(p)
{
printf("%d %d",p->c,p->e);
p=p->next;
while(p)
{
printf(" %d %d",p->c,p->e);
p=p->next;
}
}
else
{
printf("0 0");
}
}
int main()
{
scanf("%d",&n1);
head1=creatList(n1);
scanf("%d",&n2);
head2=creatList(n2);
head3=multiList(head1,head2);
printList(head3);
printf("\n");
head4=addList(head1,head2);
printList(head4);
//销毁链表
head1=clearList(head1);
head2=clearList(head2);
head3=clearList(head3);
head4=clearList(head4);
//释放头节点
free(head1);
free(head2);
free(head3);
free(head4);
return 0;
}
C++实现
利用map容器存储多项式,每一项的系数为value,幂数为key, map容器默认升序排序,这里我们将其定义为降序排序。
#include <iostream>
#include <map>
using namespace std;
int main()
{
int n1,n2;//多项式的项数
map<int,int,greater<int>>map1;//用map容器存储多项式的系数和指数
map<int,int,greater<int>>map2;//指数为key,系数为value
map<int,int,greater<int>>map3;//多项式的乘积
int c;//多项式的系数
int e;//多项式的指数
cin>>n1;
for(int i=0; i<n1; i++)
{
cin>>c>>e;
map1.insert({e,c});
}
map<int,int,greater<int>>map4(map1);//多项式的和
cin>>n2;
for(int i=0; i<n2; i++)
{
cin>>c>>e;
map2.insert({e,c});
}
if(n1+n2)//n1,n2均不为零
{
for(map<int,int>::iterator p1=map1.begin(); p1!=map1.end(); p1++)//计算多项式的乘积
{
for(map<int,int>::iterator p2=map2.begin(); p2!=map2.end(); p2++)
{
e=p1->first+p2->first;
c=p1->second*p2->second;
map3[e]+=c;
}
}
map<int,int>::iterator p3=map3.begin();
while(p3!=map3.end())
{
if(!p3->second)
{
map<int,int>::iterator t=p3;
p3++;
map3.erase(t);
}
else
p3++;
}
if(map3.size()) //如果不是零多项式
{
map<int,int>::iterator p=map3.begin();
cout<<p->second<<" "<<p->first;
p++;
while(p!=map3.end())//输出多项式的乘积
{
cout<<" "<<p->second<<" "<<p->first;
p++;
}
}
else //零多项式
{
cout<<0<<" "<<0;
}
cout<<endl;
for(map<int,int>::iterator p2=map2.begin(); p2!=map2.end(); p2++)//计算多项式的和
{
e=p2->first;
c=p2->second;
map4[e]+=c;
}
map<int,int>::iterator p4=map4.begin();
while( p4!=map4.end())//去除零项
{
if(!p4->second)
{
map<int,int>::iterator t=p4;
p4++;
map4.erase(t);
}
else
p4++;
}
if(map4.size()) //如果不是零多项式
{
map<int,int>::iterator p=map4.begin();
cout<<p->second<<" "<<p->first;
p++;
while(p!=map4.end())//输出多项式的和
{
cout<<" "<<p->second<<" "<<p->first;
p++;
}
}
else //零多项式
{
cout<<0<<" "<<0;
}
}
else
{
cout<<0<<" "<<0<<endl;
cout<<0<<" "<<0;
}
return 0;
}
个人总结
在写C链表时,我总是忘记将指针指向下一个节点,整出来好几个无限循环,老毛病了。有时节点已经被我释放了,但后面还在用,这个错误也犯了几次。
写C++程序时,有的迭代器指向的键值对被我删除后,后面还在使用它,老毛病了。
其它
这两个程序都不够完善,仅供参考。如果有不好的地方,欢迎指正。