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

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

大家好,我是小白莲,今天小白莲给大家介绍的是用有序链表实现一元多项式的加法

主要思想:
设Pa和Pb为两个有序(指数从小到大)的一元多项式
实现Pa=Pa+Pb

1.若Pb中的某项的指数与Pa中的某项的指数相等,再判断这两项的系数和是否为零。
若和为零,删除Pa中的对应项;若和不为零,将Pb对应项的系数加在Pa对应项的系数上。

2.若Pb中的某项指数与Pa中的所有项的指数都不相等
(1)Pa中有大于Pb中某项指数的项。将Pb中对应的项插入Pa中第一个比Pb对应的项插指数大的前一个位置
(2)Pa中无大于Pb中某项指数的项。将Pb中剩下的所有大于Pa中指数的项插入Pa的尾部

具体操作 ,我在代码中的注释写得很清楚
好,接下来看代码

哈哈哈,看到这么多代码是不是被吓到懵逼了,其实主要思想就是我上面讲的,只不过我把很多调用的函数一起贴了出来,可以从底下的AddPolyn函数看起,整个程序的逻辑也就在这个函数上面

//包含头文件
#include
#include

//定义常量
#define OK 1
#define ERROR 0
typedef int Status;

//定义多项式结构
typedef struct 
{
	float coef;	//系数
	int	expn;	//指数
	int length;	//项数
}term,ElemType;

//定义链表结构
typedef struct PNode
{
	ElemType data;	//链表的数据域
	struct PNode* next;	//链表的指针域
}PNode, * LinkList;

//用带头结点的有序链表来表示多项式
typedef LinkList polynomail;

//有序判定函数
int compare(int a, int b) {
	if (a == b)return 0;
	else if (a > b)return 1;
	else if (a < b) return -1;
}//compare

//创建一个给链表初始化的函数
void InitList(polynomail& P) {
	//创建一个空链表
	P = (LinkList)malloc(sizeof(PNode));
	//带头结点
	P->next = NULL;
	//初始化时项数为0
	P->data.length = 0;
}//InitList


//创建一个将指定元素插入链表第i个位置的函数
Status InsertElem(polynomail& P,int i,ElemType e) {
	//创建一个新的结点
	polynomail NewNode;
	NewNode = (LinkList)malloc(sizeof(PNode));

	//创建一个指针x,指向P的结点
	polynomail x,q;
	x = P;
	//以j为计数器
	int j = 0;
	//找到第i-1个结点 
	while (x->next && j<i-1)
	{
		x = x->next;
		++j;
	}
	//判断第i个位置的结点是否存在和i的合法性
	if (!(x->next) || j > i - 1)	return ERROR;

	//开始将结点插入链表
	q = x->next;
	x->next = NewNode;
	NewNode->next = q;
	NewNode->data = e;
	//每插入一个结点项数加一
	P->data.length++;
	return OK;
}//InsertElem

//创建一个删除链表第i个位置的结点的函数
Status DeleteElem(polynomail& P,int i) {
	//创建一个指针x指向P
	polynomail x,q;
	x = P;
	//以j作为计数器
	int j = 0;

	//找到P的第i-1个结点
	while (x->next && j<i-1)
	{
		x = x->next;
		++j;
	}
	//判断第i个结点是否存在,并判断i是否合法
	if (!(x->next) || j > i-1) return ERROR;

	//删除第i个结点
	q = x->next;
	x->next = q->next;
	free(q);
	//每删除一个结点,项数减一
	P->data.length--;
	return OK;
}//DeleteElem

//若compare为0,position为链表P中与相比元素相等的位置,并返回true,
//否则,compare为1,position为链表P中与相比元素,链表P中第一个大相比元素的位置;
//compare为-1,position为-1,表示接下来的相比元素都会比链表P中的元素大;返回false
Status LocateElem(polynomail P, ElemType e, int &position,int(*compare)(int,int)) {
	polynomail x;
	x = P->next;
	int i = 1;
	int flag = -1;
	while (x)
	{
		flag = compare(x->data.expn, e.expn);
		if (!flag) break;
		if (flag == 1) {
			position = i;
			break;
		}
		x = x->next;
		++i;
	}
	//如果指数相等
	if (!flag) {
		//把P的对应元素位置返回
		position = i;
		return true;
	}
	else 
	{
		if (flag == -1)
			//若Pb接下来的指数大于Pa的所有元素的指数
			position = -1;
		return false;
	}
}//LocateElem

//获取链表第i个位置的结点,用指针x返回
Status  GetElem(polynomail P, int i, polynomail& x) {
	//创建指针x指向P的结点
	x = P->next;
	//以j作计数器
	int j = 1;
	while (x && j < i)
	{
		++j;
		x = x->next;
	}
	//判断第i个元素时候存在,并判断i的合法性
	if (!x || j > i) return ERROR;
	return OK;
}//GetElem


//创建一个表示一元多项式的函数(m项)
//创建新结点,给新结点赋值并将结点插入链表(尾插法)
void CreatPolyn(polynomail& P, int m) {
	//调用InitList函数给P初始化
	InitList(P);
	polynomail NewNode, x;
	x = P;
	ElemType e;
	int position;
	for (int i = 1; i <= m; i++)
	{
		scanf_s("%f%d", &e.coef,&e.expn);

		//如果当前链表不存在该指数项,则将其生成结点并插入链表
		if (!LocateElem(P, e, position, (*compare))) {
			//创建新的结点
			NewNode = (LinkList)malloc(sizeof(PNode));
			//把e赋给新节点的指针域
			NewNode->data = e;
			NewNode->next = NULL;
			//将结点插入链表
			x->next = NewNode;
			//让指针x一直指向链表P的尾节点
			x = x->next;
			//每进行一次新的结点插入,项数加一
			P->data.length++;
		}	
	}
}//CreatPolyn


//两个有序(指数从小到大)多项式进行加法运算Pa=Pa+Pb (指数为正整数)
void AddPolyn(polynomail& Pa, polynomail Pb) {
	//创建指针p1,p2分别指向Pa、Pb
	polynomail  p1, p2;
	p2 = Pb;
	int position;

	//遍历有序多项式Pb
	//1.若Pb中的某项的指数与Pa中的某项的指数相等,再判断这两项的系数和是否为零。
	//若和为零,删除Pa中的对应项;若和不为零,将Pb对应项的系数加在Pa对应项的系数上。

	//2.若Pb中的某项指数与Pa中的所有项的指数都不相等
	//(1)Pa中有大于Pb中某项指数的项。将Pb中对应的项插入Pa中第一个比Pb对应的项插指数大的前一个位置
	//(2)Pa中无大于Pb中某项指数的项。将Pb中剩下的所有大于Pa中指数的项插入Pa的尾部
	while (p2 = p2->next)
	{
		//以f1、f2分别为Pa,Pb中某项的系数
		float f1, f2;
		f2 = p2->data.coef;
	
		if (LocateElem(Pa, p2->data, position, (*compare))) {
			//如果指数相等

			//获取Pa中与Pb指数相同项的系数
			if (GetElem(Pa, position, p1)) 
				f1 = p1->data.coef;
			else
				printf("获取元素操作出错!\n");
			

			if ((f1 + f2)!=0) {
				//系数和不为零,将Pb的系数加在Pa上
				p1->data.coef += f2;
			}
			else {
				//系数和为零,将对应的Pa项元素删除
				if (DeleteElem(Pa, position))
					continue;
				else 
					printf("删除元素操作出错!\n"); 
			}
		}
		else {
			//若指数不相等
	
			if (position != -1) {
				//Pa中有大于Pb中某项指数的项,
				//则将Pb中对应的项插入Pa
				if (InsertElem(Pa, position, p2->data))
					continue;
				else
					printf("插入元素操作出错!\n");
			}
			else
			{
				//Pa中无大于Pb中某项指数的项
				//将剩余Pb的所有项直接插入Pa尾部
				if (GetElem(Pa, Pa->data.length, p1)) 
					p1->next = p2;
				else
					printf("获取元素操作出错!\n");
				//遍历完毕中断循环
				break;
			}
		}
	}
}//AddPolyn

//创建一个输出多项式所有元素的函数
void MyPrint(polynomail& P) {
	polynomail x;
	x = P->next;
	if (x == NULL) printf("当前链表为空表!!!");
	while (x)
	{
		printf("%.2fx%d ", x->data.coef, x->data.expn);
		x = x->next;
	}
	printf("\n\n");
}//MyPrint

//测试
int main() {
	polynomail Pa,Pb;
	//CreatPolyn函数第2个参数为需要输入多项式的项数
	CreatPolyn(Pa, 5);
	printf("Pa:\n");
	MyPrint(Pa);

	CreatPolyn(Pb, 8);
	printf("Pb:\n");
	MyPrint(Pb);

	AddPolyn(Pa, Pb);

	printf("ADDPa:\n");
	MyPrint(Pa);

	return 0;
}




测试结果

一元多项式的加法(链表的应用)_第1张图片
end

当然,如果觉得小白莲写得还不错,记得一定!一定!要点个赞再走哦!最好关注一下也是可以的,你们的对我的点赞和关注就是对我最大的支持,我真的很需要,谢谢!说的就是你,光收藏却不点赞,哼~~

给人点赞,手留余香

预知后续操作如何,请看下集

@author 白莲居仙 QQ:1131977233

你可能感兴趣的:(线性表的链式存储结构,一元多项式的加法,链表的应用)