单链表实现多项式的表示及加减运算

这篇博客介绍了如何使用单链表实现一元稀疏多项式的加法和减法运算。通过尾插法创建多项式链表,然后进行按位匹配和运算,输出按指数降序排列的结果。加法中相同指数的项相加,减法中考虑了系数相减小于等于0的情况。博客提供了多个运行实例展示算法的正确性。

多项式的表示及运算
[问题描述]
设计一个算法,以实现一元稀疏多项式的加法运算。
[基本要求]
(1)输入并建立多项式;
(2)输出多项式,输出形式为整数序列:n,c1,e1,c2,e2,……,cn,en,其中n是多项式的项数,ci和ei分别是第i项的系数和指数,序列按指数降序排列;
(3)多项式a和b相加,建立多项式a+b。
[测试数据]
由学生任意指定。
[实现提示]
  用带表头结点的单链表存储多项式。
[选作内容]
  多项式a和b相减,建立多项式a-b。
  
单链表的创建与基本操作

多项式加法:

实现:
创建新表K存放加法运算后的多项式;
输入数据后我们先用while (getelem1(L,x)) x++;查看L,J多项式的格式;
接着利用指针进行类似模式匹配,按位比较指数,输出高位并向后移动高位所在链表的指针,如果指数相同则进行运算并同时移动两个指针;
最后判断如果其中一个表匹配到尾,就将另一个表接在K表后面,最后输出K表。

typedef struct LNode
{
	int data;//存放系数
	int num;//存放指数
	LNode* next;
}LNode,*LinkList;
void InitList(LinkList &L)//初始化
{
	L=new LNode;
	L->next=NULL;
}
void CreateListTail1(LinkList &L,int n)//尾插法建表
{
	LinkList p,r;
	L=new LNode;
	r=L;
	for (int i = 1; i <= n; i++)
	{
		p=new LNode;
		cin>>p->data;
		cin>>p->num;
		r->next=p;
		r=p;
	}
	r->next=NULL;
}
bool getelem1(LinkList L,int i)//查找并输出L中第i个元素的数据
{
	LinkList p=L->next;
	int j=1;
	while (p&&j<i)
	{
		p=p->next;
		++j;
	}
	if(!p||j>i) return false;
	else cout<<p->data<<' '<<p->num<<' ';
	return true;
}
void add() //算法部分
{
	LinkList L,J;
	LinkList K;//创建新表
	InitList(K);
	int m,n;
	cin>>m>>n;
	CreateListTail1(L,m);
	CreateListTail1(J,n);
	//查看L,J表的格式
	int x=1;
	while (getelem1(L,x)) x++;
	x=1;
	cout<<endl;
	while (getelem1(J,x)) x++;
	cout<<endl;
	//
	LinkList p=L->next,q=J->next,k=K;
	while (p&&q)
	{
		LinkList e=new LNode;
		if (p->num==q->num)
		{
			e->data=p->data+q->data;
			e->num=p->num;
			k->next=e;
			k=k->next;
			p=p->next;
			q=q->next;
		}
		else if(p->num>q->num)
		{
			e=p;
			p=p->next;
			k->next=e;
			k=k->next;
		}
		else if (p->num<q->num)
		{
			e=q;
			q=q->next;
			k->next=e;
			k=k->next;
		}
	}
	if (!p) k->next=q;
	else if (!q) k->next=p;
	x=1;
	while (getelem1(K,x)) x++;	
}

多项式减法:

与多项式加法实现略有不同,减法考虑当同指数系数相减<=0时的特殊情况。
所以匹配过程中被减数项p不用变号,需要改变减数项q。如果q为高指数位置,则对q的系数取反,还需要修改最后的链接时q的值。
最后利用judge(LinkList L)函数输出多项式,并判断特殊情况:如果没有项输出,则说明值为0。

void judge(LinkList L)
{
	int tot=0;
	LinkList p=L->next;
	while (p)
	{
		if(p->data==0) ;//如果系数为0,则直接跳过
		else 
		{
			cout<<p->data<<' '<<p->num<<' ';
			tot++;
		}
		p=p->next;
	}
	if(!tot) cout<<'0'<<endl;//特殊条件的判断
}
void sub()
{
	LinkList L,J;
	LinkList K;
	InitList(K);
	int m,n;
	cin>>m>>n;
	CreateListTail1(L,m);
	CreateListTail1(J,n);
	int x=1;
	while (getelem1(L,x)) x++;
	x=1;
	cout<<endl;
	while (getelem1(J,x)) x++;
	cout<<endl;
	LinkList p=L->next,q=J->next,k=K;
	while (p&&q)
	{
		LinkList e;
		if (p->num==q->num)
		{
			e=new LNode;
			e->data=p->data-q->data;
			e->next=NULL;
			//if(e->data<0) e->data=0;
			e->num=p->num;
			p=p->next;
			q=q->next;
			k->next=e;
			k=k->next;			
		}
		else if(p->num>q->num)
		{
			e=p;
			p=p->next;
			k->next=e;
			k=k->next;
		}
		else if (p->num<q->num)
		{
			q->data=0-q->data;
			e=q;
			q=q->next;
			k->next=e;
			k=k->next;
		}
	}
	if (!p)
	{
	//将剩余q链表链接时要对所有剩下项的系数取反
		LinkList r=q;
		while (q)
		{
			q->data=0-q->data;
			q=q->next;
		}
		k->next=r;
	}
	else if (!q) k->next=p;
	judge(K);
}

运行实例

加法:
实例一:
In:4 4 4 6 3 5 2 4 1 3 4 4 3 3 2 2 1 1
Ou:4 6 3 5 2 4 1 3
4 4 3 3 2 2 1 1
4 6 3 5 6 4 4 3 2 2 1 1
实例二:
4 4 4 4 3 3 2 2 1 1 4 6 3 5 2 4 1 3
4 4 3 3 2 2 1 1
4 6 3 5 2 4 1 3
4 6 3 5 6 4 4 3 2 2 1 1
实例三:
4 4 4 4 3 3 2 2 1 1 4 4 3 3 2 2 1 1
4 4 3 3 2 2 1 1
4 4 3 3 2 2 1 1
8 4 6 3 4 2 2 1

减法:
实例一:
4 4 4 6 3 5 2 4 1 3 4 4 3 3 2 2 1 1
4 6 3 5 2 4 1 3
4 4 3 3 2 2 1 1
4 6 3 5 -2 4 -2 3 -2 2 -1 1
实例二:
4 4 4 4 3 3 2 2 1 1 4 6 3 5 2 4 1 3
4 4 3 3 2 2 1 1
4 6 3 5 2 4 1 3
-4 6 -3 5 2 4 2 3 2 2 1 1
实例三:
4 4 4 4 3 3 2 2 1 1 4 4 3 3 2 2 1 1
4 4 3 3 2 2 1 1
4 4 3 3 2 2 1 1
0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新西兰做的饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值