一元多项式相加(单链表的应用)

#include<stdio.h>
#include<stdlib.h> 
typedef struct Lnode
{
	float coef;//系数
	int expn;//指数 
	struct	Lnode *next;
 } Lnode,*Linknode;
 void init(Linknode &L)   //初始化L 
 {
 	L=(Linknode)malloc(sizeof(Linknode));
 	L->next=NULL;
 }
 void enter(Linknode &L,int e,float c)  //尾插法插入一个元素 
 {
 	Linknode p=L;
 	while(p->next!=NULL)
 	{
 		p=p->next;	
	}
	Linknode s=(Linknode)malloc(sizeof(Lnode));
 	s->coef=c;
 	s->expn=e;
 	s->next=p->next;
 	p->next=s;
 }
 void  destory(Linknode &L)  //销毁单链表 
 {
 	Linknode p=L->next,p1;
 	while(p!=NULL)
 	{
 		p1=p->next;
		 free(p);	
	}
	free(L);
 }
  void print(Linknode L)  //遍历单链表 
  {
  	Linknode p=L->next;
  	while(p!=NULL)
  	{
  		printf("%fx^%d ",p->coef,p->expn);
  		if(p->next!=NULL)
  			printf(" + ");
  		p=p->next;
	  }
  }
   int length(Linknode L)  //获取单链表长度 
  {
  	Linknode p=L->next;
  	int i=0;
  	while(p!=NULL)
  	{
  		i++;
  		p=p->next;
	  }
	return i;
  }
  bool at(Linknode L,int e,Linknode &q) //判断e是L链表中哪一个节点中系数的值 
  {
  	Linknode p=L->next;
  	while(p!=NULL)
  	{
  		if(p->expn==e)
  		{
  			q=p;
  			return true;
		}
		else
		{
			p=p->next;
		}
  	}
  	q=NULL;
  	return false;
  }
  void combine(Linknode &L1,Linknode L2)  //将L1,L2链表按照顺序合并 
  {
  	Linknode p1=L1->next,r=L2->next,p2;
  	L2->next=NULL;
	while(r!=NULL)
	{
	  		p2=r;
	  		r=r->next;
	  		while(p1!=NULL)
			{
				if(p1->expn<p2->expn)
				{
					if(p1->next==NULL)
					{
						p2->next=p1->next;
						p1->next=p2;
						break;
					}
					else if(p1->next->expn>p2->expn)
					{
						p2->next=p1->next;
						p1->next=p2;
						break;
					}
				}
				p1=p1->next;
			}	
	}
  }
 void add(Linknode &L1,Linknode L2) //总函数:将L1,L2两个多项式相加,
 //我未增加一个新链表而是将L2链表合到L1上以减少空间复杂度
 //还有一个思路:新建一个链表一次遍历L1,L2:若L1,L2上的指数相同则在L3上新加一个结点; 
 //若L1指数>L2将L2上结点放到L3上,L1指针后移,反之,L2指针后移,L1当前节点放到L3上
 //此思路增加了空间复杂度减少了时间复杂度 
 {
 	{
 		Linknode p1=L1->next,q1;
 		while(p1!=NULL)
 		{
 			if(at(L2,p1->expn,q1))
 			{
 				p1->coef+=q1->coef;
 				q1->expn=-1;
			 }
			 else
			 {
			 	p1=p1->next;
			 }
		}
		Linknode q2=L2->next,q2_pre=L2;
		while(q2!=NULL)
		{
			if(q2->expn==-1)
			{
				q2_pre->next=q2->next;
				free(q2);
				q2=q2_pre->next;
			}
			else
			{
				q2=q2->next;
				q2_pre=q2_pre->next;
			}
		}
		combine(L1,L2); 
	 }
 }
 void create(Linknode &L)
 {
 	int n; 
 	printf("请输入多项式的项数:\n");
 	scanf("%d",&n);
 	for(int i=0;i<n;i++)
 	{
 		int e;
		float c;
 		printf("请输入系数:\n");
 		scanf("%f",&c);
 		printf("请输入指数:\n");
 		scanf("%d",&e);
 		enter(L,e,c);
	 }
 }
 int main()
 {
 	Linknode L1,L2;
 	int n; 
 	init(L1);
 	init(L2);
 	create(L1);
 	create(L2);
 	printf("L1多项式:\n");
 	print(L1);
 	printf("\n");
 	printf("L2多项式:\n");
 	print(L2);
 	printf("\n");
 	printf("================\n");
 	add(L1,L2);
 	print(L1);
 	destory(L1);
 	destory(L2);
 	return 0;
 }

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值