一元多项式的相加

一元多项式:一元多项式
可以用一个线性表P来表示:
在这里插入图片描述
Pn(x)线性表表示法每一项的指数从系数下标即可表示
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1.采用顺序存储结构来存系数,对应单元的内容相加即可。
在这里插入图片描述
但在通常的应用中,多项式的指数有时可能会变化很高并且变化很大,如下图
在这里插入图片描述
用一长度为20001的线性表来表示,表中仅有3个非零元素,浪费空间。所以我们可以存储非零系数项和相应的指数。

假设一元多项式:
在这里插入图片描述
线性表表示:只存非零系数,多项式中每一项由指数项和系数项构成。用单链表实现。
在这里插入图片描述
1.结构描述

结点包含两个数据域:一个是系数coef,另一个是指数exp。

多项式结点结构:
在这里插入图片描述

typedef struct  Polynode 
{
    int coef;  //系数
    int exp;   // 指数
    Polynode *next;
} LinkListNode;

2.算法描述
对所有指数相同的项,将其对应系数相加,若和不为零,则构成和多项式中的一项;
将所有指数不相同的项复制到和多项式中。

和多项式采用形式:
方法一:新建
方法二:把一个多项式归并入另一个多项式

多项式 2 + 3X + 5X^3 + 2X ^4 与 3 + 2X + 4X ^2 相加
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1)方法一
/*
函数功能:将两个多项式polyA和polyB相加,然后将和多项式存放在多项式polyC中。
函数输入:polyA和polyB链的首地址
函数输出:polyC链地址
*/

伪代码描述:
设pa指向headA链、pb指向headB链
while (pa、pb两个链都没处理完)
{
if (pa、pb指向当前结点的指数项相同)
{
系数相加,当和不为零时在C链中添加新的结点;
pa、pb指针后移一位;
}
else
{
以指数小的项的系数添入C链中的新结点;
指数小的相应链指针后移;
}
}
p指向未处理完的链
while( p非空)
{ 顺序处理p链;}

程序实现:

#include<stdio.h>
#include<malloc.h>
#define ElemType int 
typedef struct  Polynode 
{
    int coef;  //系数
    int exp;   // 指数
    Polynode *next;
} LinkListNode;

LinkListNode *attach(ElemType c, int e, LinkListNode* pc);
/*=====================================================
函数功能:将两个多项式polyA和polyB相加,然后将和多项式存放在多项式polyC中。
函数输入:polyA和polyB链的首地址
函数输出:polyC链地址
======================================================*/
LinkListNode *polyadd_headC(LinkListNode *headA, LinkListNode *headB)
{
	LinkListNode *headC;
	LinkListNode *pa, *pb, *pc, *p;
	ElemType x;
	pa=headA->next;
	pb=headB->next;
	headC=(LinkListNode*)malloc(sizeof(LinkListNode));
	pc=headC;
	while(pa&&pb)
	{
		if(pa->exp==pb->exp)
		{
			x=pa->coef+pb->coef;
			if(x!=0) pc=attach(x,pa->exp,pc);
			pa=pa->next;
			pb=pb->next;
			continue;
		}
		if(pa->exp < pb->exp)
		{p=pa;
		pa=pa->next;
		}
		else
		{p=pb;
		pb=pb->next;
		}
		pc=attach(p->coef,p->exp,pc);	
	}
	p=pa;
	if(pa==NULL) p=pb;
	while(p)
	{
		pc=attach(p->coef,p->exp,pc);
		p=p->next;
	}
	pc->next=NULL;
	return headC;
 } 
 
 /*=====================================================
函数功能:建立系数为c,指数为e的新结点,并把它插在
          pc所指结点的后面,链接后pc指向新链入的结点 
函数输入:系数c,指数e,pc地址 
函数输出:pc地址 
======================================================*/
LinkListNode *attach(ElemType c, int e, LinkListNode* pc)
{
	LinkListNode *p;
	p=(LinkListNode *)malloc(sizeof(LinkListNode));
	p->coef=c;
	p->exp=e;
	pc->next=p;
	return p;
 } 

2)方法二:

将两个多项式polyA和polyB相加,然后将和多项式存放在多项式polyA中,并将多项式ployB删除。
/==================================================
函数功能: 将两个多项式polyA和polyB相加,结果存放在polyA中
函数输入:polyA和polyB链首地址
函数输出:无
====================================================
/

伪代码如下:
设pa指向headA链、pb指向headB链
while (pa、pb两个链都没处理完)
{
if (pa、pb指向当前结点的指数项相同)
{ 两个结点中的系数相加;
当和不为零时修改结点pa的系数域,释放pb结点;
若和为零,则和多项式中无此项,删去pa结点,同时释放pa和pb结点。
continue;
}
if (pa指数小于pb指数)
{ pa结点应是“和多项式”中的一项,pa后移;
continue;
}
if (pa指数大于pb指数)
{ pb结点应是“和多项式”中的一项,将pb插入在pa之前,
pb后移;
continue;
}
}
若pb非空,将其加入pa链尾。

程序实现:

/*==================================================
函数功能: 将两个多项式polyA和polyB相加,结果存放在polyA中
函数输入:polyA和polyB链首地址
函数输出:无
====================================================*/
void polyadd_headA(LinkListNode *polyA, LinkListNode *polyB) 
{
	LinkListNode *pa, *pb, *pre, *temp;
	int sum;

	//令 pa 和 pb 分别指向polyA 和 polyB 多项式链表中的第一个结点
	pa=polyA->next;
	pb=polyB->next;

	pre=polyA;  //pre 指向和多项式的尾结点
	while(pa!=NULL&&pb!=NULL) //当两个多项式均未扫描结束时
	{ 
		if(pa->exp==pb->exp) //若指数相等
		{ 
			sum=pa->coef+pb->coef;  //相应的系数相加
			if(sum!=0) //若系数和非零
			{ 
				pa->coef=sum;
				pre->next=pa;
				pre=pre->next;
				pa=pa->next;
				temp=pb;
				pb=pb->next;
				free(temp);
				continue;
			} 
			else //若系数和为零
			{ 
				temp=pa->next;
				free(pa);
				pa=temp;
				temp=pb->next;
				free(pb);
				pb=temp;
				continue;
			}
		}
		
		if(pa->exp<pb->exp)  //pa的指数大于pb的指数
		//pa与pre指针后移
		{
			pre->next=pa;
			pre=pre->next;
			pa=pa->next;
			continue;
		}
		if(pa->exp>pb->exp)  //pa的指数小于pb的指数
		//将pb结点加入到pa前
		{
			pre->next=pb;
			pre=pre->next;
			pb=pb->next;
			pre->next=pa;
			continue;
		 } 
	}
	if(pb!=NULL)  //将剩余的pb加入到和多项式中
	pre->next=pb;
}

/*==================================================
函数功能: 用尾插法建立一元多项式的链表 
函数输入:多项式系数与指数数组、多项式项数 
函数输出:多项式链表首地址 
====================================================*/
LinkListNode *CreateList_Rear(ElemType a[][2], int n) 
{
	LinkListNode *head, *p, *q;
	int i;
	
	head=(LinkListNode *)malloc(sizeof(LinkListNode));
	q=head;
	for(i=0; i<n; i++)
	{
		p=(LinkListNode *)malloc(sizeof(LinkListNode));
		p->coef=a[i][0];
		p->exp=a[i][1];
		q->next=p;
		q=p;
	}
	p->next=NULL;
	return head;
}

3.程序测试

#include<stdio.h>
#include<malloc.h>

LinkListNode *CreateList_Rear(ElemType a[][2], int n);
LinkListNode *polyadd_headC(LinkListNode *polyA, LinkListNode *polyB);
LinkListNode *attach(ElemType c, int e, LinkListNode *polyB);
void polyadd_headA(LinkListNode *polyA, LinkListNode *polyB);
void PrintList(LinkListNode *L);

int main()
{
	int a[][2]={{3,14},{2,8},{1,6}};
	int b[][2]={{8,14},{-3,10},{10,6},{1,0}};
	LinkListNode *headA, *headB;
	LinkListNode *linkPtr;
	
	headA=CreateList_Rear(a,3);
	headB=CreateList_Rear(b,4);
	linkPtr=polyadd_headC(headA,headB);
	printf("另建多项式保存时:\n");
	PrintList(linkPtr);
	polyadd_headA(headA,headB);
	printf("将和多项式保存A中时:\n") ; 
	PrintList(headA);
	return 0;
 } 
void PrintList(LinkListNode *L)
{
	LinkListNode *p;
	p=L->next;//跳出头结点
	int i=1;
	while(p)//链表为空
	{
		printf("第%d项系数是%d,次方是%d\n",i,p->coef,p->exp);
		i++;
		p=p->next;	
	}
}

测试结果:结果显然输出不对,不过没找到错误。
以后再说吧
在这里插入图片描述

小结:处于初学阶段,相比以前觉得索然无味,现在感觉算是一个个小挑战,不断学习,提高代码水平。越往后学习要更快、更有质量、更要坚持。

附:顺序表和链表的比较
在这里插入图片描述
顺序存储
优点:
方法简单,容易实现。
无额外的存储开销。
随机存取,简洁便利。
缺点:
插入删除操作运算效率低。
需要预先分配足够大的存储空间,估计过大,可能会导致顺序表后部大量闲置;预先分配过小,又会造成溢出。

链式存储主要优点
无需事先了解线性表的长度。
允许线性表的长度有很大变化。
能够适应经常插入、删除内部元素的情况。
通过建立双向或循环链表提高访问效率

线性表存储结构的选用考量
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值