按照数据结构的课本,本节知识将介绍多项式的一些操作,这里只实现了多项式相加,多项式的数据结构就是一个系数,一个指数,一个next指针,如下:
struct Poly{
float coef; //系数
int expn; //指数
struct Poly *next;
};
创建链表的采用的头插法,前面已介绍过,因为头插法和原来的数据正好想法,所以排序的时候就能知道了,比如输入是按照指数升序的方式,插入就是降序,排序之后又变回了升序,头插法代码,如下:
struct Poly *headInsert(int m){
struct Poly *head=NULL, *p=NULL;
float coef;
int expn,i;
for(i=0;i<m;i++){
scanf("%f%d",&coef,&expn); //未考虑指数相同的情况的结点
p=(struct Poly*)malloc(sizeof(struct Poly));
p->coef=coef;
p->expn=expn;
p->next=NULL;
if(head==NULL){
head=(struct Poly*)malloc(sizeof(struct Poly));
head->next=p;
}
else{
p->next=head->next;
head->next=p;
}
}
return head;
}
接着是冒泡排序算法,前面都已介绍过
struct Poly * bubbleSort(struct Poly *head){
if(head==NULL) return NULL;
struct Poly *p=NULL,*tail=NULL;
while(head->next->next!=tail){
for(p=head;p->next->next!=tail;p=p->next){
if(p->next->expn>p->next->next->expn){
struct Poly *q=p->next;
p->next=q->next;
q->next=p->next->next;
p->next->next=q;
}
}
tail=p->next;
}
return head;
}
然后就是核心的多项式相加,相加的过程,我用的是用多项式A记录两个相加的结果,而不是重新开辟一个多项式C,记录两者相加。
先开始认为挺简单的,结果发现不是那样,对于多项式A和多项式B,头结点分别为head1和head2,对于多项式A和多项式B都需要两个指针,一个指向当前结点,一个是指向当前结点的前驱结点
1.因为相加的过程涉及到对多项式A和多项式B的结点的插入和删除,比如两个结点的指数相同且系数相加为0,多项式A就需要删除当前结点,B可以不删除,继续next即可
2.当多项式B的当前结点的指数小于多项式A的当前结点的的指数时就必须将B的当前结点插入到多项式A中,这样的两个操作都需要有前驱指针,否则一删除或者插入就不知道指向哪儿了。
3.还需注意,任意浮点数可以0直接比较就是了,但是, 任意两个浮点是不能用==直接比较,当然最严谨的还是abs(val) < 0.0000001或者if (x < 0.000001 && x > -0.000001)
代码如下:
int cmp(int a,int b){
if(a>b) return 1;
else if(a<b) return -1;
else return 0;
}
struct Poly *addPoly(struct Poly *head1,struct Poly *head2){
if(head1==NULL||head2==NULL) return NULL;
struct Poly *qa=head1->next,*qb=head2->next,*qaPre=head1,*qbPre=head2;
while(qa&&qb){
int e1=qa->expn,e2=qb->expn;
float sum=0;
switch(cmp(e1,e2)){
case -1:
qaPre=qa;
qa=qa->next;
break;
case 0:
sum=qa->coef+qb->coef;
if(sum==0){
qaPre->next=qa->next;
qa=qaPre->next;
}
else{
qa->coef=sum;
}
qbPre=qb;
qb=qb->next;
break;
case 1:
qbPre->next=qb->next;
qb->next=qa;
qaPre->next=qb;
qaPre=qb;
qb=qbPre->next;
break;
}
}
while(qb){
qaPre->next=qb;
qb=qb->next;
}
return head1;
}
总的代码如下,main函数中注释的代码,是为了测试,也是为了知道当前输入是什么
#include <stdio.h>
#include <stdlib.h>
struct Poly{
float coef; //系数
int expn; //指数
struct Poly *next;
};
struct Poly *headInsert(int );
struct Poly * bubbleSort(struct Poly *);
void display(struct Poly *);
struct Poly *addPoly(struct Poly *,struct Poly *);
int cmp(int ,int );
struct Poly *headInsert(int m){
struct Poly *head=NULL, *p=NULL;
float coef;
int expn,i;
for(i=0;i<m;i++){
scanf("%f%d",&coef,&expn); //未考虑指数相同的情况的结点,也就是输入的指数都不相同
p=(struct Poly*)malloc(sizeof(struct Poly));
p->coef=coef;
p->expn=expn;
p->next=NULL;
if(head==NULL){
head=(struct Poly*)malloc(sizeof(struct Poly));
head->next=p;
}
else{
p->next=head->next;
head->next=p;
}
}
return head;
}
struct Poly * bubbleSort(struct Poly *head){
if(head==NULL) return NULL;
struct Poly *p=NULL,*tail=NULL;
while(head->next->next!=tail){
for(p=head;p->next->next!=tail;p=p->next){
if(p->next->expn>p->next->next->expn){
struct Poly *q=p->next;
p->next=q->next;
q->next=p->next->next;
p->next->next=q;
}
}
tail=p->next;
}
return head;
}
void display(struct Poly *head){
if(head==NULL) return ;
struct Poly *tmp=head->next;
while(tmp){
printf("%f %d ",tmp->coef,tmp->expn);
tmp=tmp->next;
}
printf("\n");
}
int cmp(int a,int b){
if(a>b) return 1;
else if(a<b) return -1;
else return 0;
}
struct Poly *addPoly(struct Poly *head1,struct Poly *head2){
if(head1==NULL||head2==NULL) return NULL;
struct Poly *qa=head1->next,*qb=head2->next,*qaPre=head1,*qbPre=head2;
while(qa&&qb){
int e1=qa->expn,e2=qb->expn;
float sum=0;
switch(cmp(e1,e2)){
case -1: //当A的指数小的时候,就继续next
qaPre=qa;
qa=qa->next;
break;
case 0:
sum=qa->coef+qb->coef;
if(sum==0){ //指数相同且和为0,删除A的当前结点
qaPre->next=qa->next;
qa=qaPre->next;
}
else{
qa->coef=sum;
}
qbPre=qb; //无论和是否为0,B都需要next
qb=qb->next;
break;
case 1: //当B的指数小于A的指数时,就插入B的当前结点
qbPre->next=qb->next;
qb->next=qa;
qaPre->next=qb;
qaPre=qb;
qb=qbPre->next;
break;
}
}
while(qb){
qaPre->next=qb;
qb=qb->next;
}
return head1;
}
int main(){
int m,n;
printf("分别输入两个多项式的长度\n");
scanf("%d%d",&m,&n);
//printf("输入第一个多项式的数据(先系数后指数)\n");
struct Poly *head1=headInsert(m);
//printf("排序前的数据\n");
//display(head1);
//printf("排序后的数据\n");
head1=bubbleSort(head1);
//display(head1);
//printf("输入第二个多项式的数据(先系数后指数)\n");
struct Poly *head2=headInsert(n);
//printf("排序前的数据\n");
//display(head2);
//printf("排序后的数据\n");
head2=bubbleSort(head2);
//display(head2);
head1=addPoly(head1,head2);
display(head1);
return 0;
}
未完待续:下一章 栈和队列算法一之栈的基本操作
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权