链表算法六之多项式相加

    按照数据结构的课本,本节知识将介绍多项式的一些操作,这里只实现了多项式相加,多项式的数据结构就是一个系数,一个指数,一个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;
}


未完待续:下一章 栈和队列算法一之栈的基本操作


如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步

文章转载请注明出处,请尊重知识产权

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值