一元多项式的表示及相加(C语言版)

运算法则

对于两个一元多项式中所有指数相同的项,对应系数相加,若其和不为0,则构成和多项式的一项;对于两个一元多项式中所有指数不相同的项,分别复制到和多项式中

一元多项式表示相加的实现

准备工作

代码所需头文件、构造一个链表表示一元多项式与实现所需要的函数原型

#define _CRT_SECURE_NO_WARNINGS 

#include <stdio.h>
#include <stdlib.h> 

typedef struct PolyNode{
	int coef; //系数
	int expn; //指数
	struct PolyNode* next; //指向下一个结点
}Polynomial;

void CreatPolyn(Polynomial** P, int m); //建立表示一元多项式的有序链表p
void DestroyPolyn(Polynomial** P); //销毁一元多项式P
void PrintPolyn(Polynomial* poly); //打印多项式
int PolynLength(Polynomial* P); //返回一元多项式的长度
void AddPolyn(Polynomial* Pa, Polynomial* Pb); //一元多项式相加并销毁Pb
void Append(Polynomial* L, Polynomial* S); //将s链接在L的最后一个结点
int compare(int a, int b); //比大小

一元多项式的建立

因为要改变头结点所以用到二级指针

void CreatPolyn(Polynomial** P, int m)
{
	int y, n;
	(*P) = (Polynomial*)malloc(sizeof(Polynomial));
	Polynomial* head = *P;
	head->next = NULL;
	Polynomial* a;
	printf("请输入多项式系数与指数用逗号隔开\n");
	while (m--)
	{
		scanf("%d,%d", &y, &n);
		a = (Polynomial*)malloc(sizeof(Polynomial));
		if (a != NULL)
		{
			a->coef = y;
			a->expn = n;
		}
		a->next = head->next;
		head->next = a;
		head = a;
	}
}

一元多项式的销毁

销毁将头节点也free,要用到二级指针

void DestroyPolyn(Polynomial** P)
{
	Polynomial* L = *P;
	Polynomial* next = NULL;
	while (L)
	{
		next = L->next;
		free(L);
		L = next;
	}
	*P = NULL;
	printf("销毁成功\n");
}

遍历一元多项式

先判断是否建立一元多项式,头结点为空则表示没有建立

void PrintPolyn(Polynomial* poly)
{
	if (poly != NULL)
	{
		Polynomial* temp = poly->next;
		printf("多项式输出如下\n");
		printf("%dX^%d", temp->coef, temp->expn);
		temp = temp->next;
		while (temp != NULL)
		{
			if (temp->coef == 0);
			else
				printf("+%dX^%d", temp->coef, temp->expn);
			temp = temp->next;
		}
		printf("\n");
	}
	else
		printf("请先建立一元多项式\n");
}

返回一元多项式元素个数

与单链表返回长度代码相同

int PolynLength(Polynomial* P)
{
	int count = 0;
	Polynomial* L = P->next;
	while (L != NULL)
	{
		L = L->next;
		count++;
	}
	return count;
}

将指针S所指的一串节点连接在L的最后一个结点

连接两个链表
注意:如果两个链表都带头指针,连接时要让S指向第一个节点在链接

void Append(Polynomial* L, Polynomial* S)
{
    Polynomial* p = L; Polynomial* q = S->next; //q为S的第一个节点
    int i;
    for (i = 1; i <= PolynLength(L); i++)
        p = p->next;  //p为L的最后一个节点
    p->next = q; 
    printf("连接成功\n");
}

比较大小函数

在一元多项式相加时比较指数需要用到

int compare(int a, int b)
{
	if (a < b)
		return -1;
	else if (a == b)
		return 0;
	else
		return 1;
}

一元多项式的相加算法

详细解释都在代码的注释里

void AddPolyn(Polynomial* Pa, Polynomial* Pb)
{
	int a, b, sum;
	Polynomial* ha = Pa; Polynomial* hb = Pb; //让ha,hb成为Pa,Pb的头结点
	Polynomial* qa = ha->next; //qa指向ha的第一个元素
	Polynomial* qb = hb->next; //qb指向hb的第一个元素
	while (qa && qb)  //qa,qb均不为NULL
	{
		a = qa->expn; b = qb->expn;  //a,b为当前结点的指数值
		switch (compare(a,b)) //比较指数大小
		{
			case -1: {        //a<b,
				ha = qa;       //ha结点向前移动一位
				qa = qa->next; //qa指向下一个节点
				break;
			}
			case 1: {        //a>b
				//移除Pb中第一个节点
				qb = hb->next; 
				hb->next = qb->next;
				//将原Pb中第一个结点连接在Pa的ha节点后面
				qb->next = ha->next;
				ha->next = qb;
				//ha结点向前移动一位
				ha = ha->next;
				qb = hb->next; //qb指向下一个节点
				break;
			}
			case 0: {      //a=b
				qa->coef = qa->coef + qb->coef; //将相同指数前的系数相加
				sum = qa->coef;
				if (sum == 0) //如果系数和为0删除此节点
				{
					qa = ha->next;
					ha->next = ha->next->next;
					free(qa);
					qa = NULL;
				}
				else      
					ha = qa; //将ha结点向前移动一位
				//删除qb结点
				qb = hb->next; 
				hb->next = hb->next->next; 
				free(qb);
				qb = NULL;
				//qb,qa各向前移动一位
				qb = hb->next;
				qa = ha->next;
				break;
			}
		}
	}
	if (Pb->next != NULL)  //Pb还有剩余
		Append(Pa, Pb);    //将Pb剩余的连接在Pa的尾部
}

完整测试函数

#define _CRT_SECURE_NO_WARNINGS 

#include <stdio.h>
#include <stdlib.h>

typedef struct PolyNode{
	int coef;
	int expn;
	struct PolyNode* next;
}Polynomial;

void CreatPolyn(Polynomial** P, int m); //建立表示一元多项式的有序链表p
void DestroyPolyn(Polynomial** P); //销毁一元多项式P
void PrintPolyn(Polynomial* poly); //打印多项式
int PolynLength(Polynomial* P); //返回一元多项式的长度
void AddPolyn(Polynomial* Pa, Polynomial* Pb); //一元多项式相加并销毁Pb
void Append(Polynomial* L, Polynomial* S); //将s链接在L的最后一个结点
int compare(int a, int b); //比大小

int main()
{
	int m;
	printf("请输入项数:");
	scanf("%d", &m);
	Polynomial* L,*S;
	CreatPolyn(&L,m);
	printf("请输入项数:");
	scanf("%d", &m);
	CreatPolyn(&S, m);
	PrintPolyn(L);
	PrintPolyn(S);
	AddPolyn(L, S);
	PrintPolyn(L);

	return 0;
}

void CreatPolyn(Polynomial** P, int m)
{
	int y, n;
	(*P) = (Polynomial*)malloc(sizeof(Polynomial));
	Polynomial* head = *P;
	head->next = NULL;
	Polynomial* a;
	printf("请输入多项式系数与指数用逗号隔开\n");
	while (m--)
	{
		scanf("%d,%d", &y, &n);
		a = (Polynomial*)malloc(sizeof(Polynomial));
		if (a != NULL)
		{
			a->coef = y;
			a->expn = n;
		}
		a->next = head->next;
		head->next = a;
		head = a;
	}
}

void DestroyPolyn(Polynomial** P)
{
	Polynomial* L = *P;
	Polynomial* next = NULL;
	while (L)
	{
		next = L->next;
		free(L);
		L = next;
	}
	*P = NULL;
	printf("销毁成功\n");
}

void PrintPolyn(Polynomial* poly)
{
	if (poly != NULL)
	{
		Polynomial* temp = poly->next;
		printf("多项式输出如下\n");
		printf("%dX^%d", temp->coef, temp->expn);
		temp = temp->next;
		while (temp != NULL)
		{
			if (temp->coef == 0);
			else
				printf("+%dX^%d", temp->coef, temp->expn);
			temp = temp->next;
		}
		printf("\n");
	}
	else
		printf("请先建立一元多项式\n");
}

int PolynLength(Polynomial* P)
{
	int count = 0;
	Polynomial* L = P->next;
	while (L != NULL)
	{
		L = L->next;
		count++;
	}
	return count;
}

void AddPolyn(Polynomial* Pa, Polynomial* Pb)
{
	int a, b, sum;
	Polynomial* ha = Pa; Polynomial* hb = Pb;
	Polynomial* qa = ha->next;
	Polynomial* qb = hb->next;
	while (qa && qb)
	{
		a = qa->expn; b = qb->expn;  //a,b为当前结点的指数值
		printf("%d %d\n", a, b);
		switch (compare(a,b)) //比较指数大小
		{
			case -1: {        //a<b,
				ha = qa;       //ha结点向前移动一位
				qa = qa->next; //qa指向下一个节点
				break;
			}
			case 1: {        //a>b
				//移除Pb中第一个节点
				qb = hb->next; 
				hb->next = qb->next;
				//将原Pb中第一个结点连接在Pa的ha节点后面
				qb->next = ha->next;
				ha->next = qb;
				//ha结点向前移动一位
				ha = ha->next;
				qb = hb->next; //qb指向下一个节点
				break;
			}
			case 0: {      //a=b
				qa->coef = qa->coef + qb->coef; //将相同指数前的系数相加
				sum = qa->coef;
				printf("%d\n", sum); 
				if (sum == 0) //如果系数和为0删除此节点
				{
					qa = ha->next;
					ha->next = ha->next->next;
					free(qa);
					qa = NULL;
				}
				else      
					ha = qa; //将ha结点向前移动一位
				//删除qb结点
				qb = hb->next; 
				hb->next = hb->next->next; 
				free(qb);
				qb = NULL;
				//qb,qa各向前移动一位
				qb = hb->next;
				qa = ha->next;
				break;
			}
		}
	}
	if (Pb->next != NULL)  //Pb还有剩余
		Append(Pa, Pb);    //将Pb剩余的连接在Pa的尾部
}

void Append(Polynomial* L, Polynomial* S)
{
    Polynomial* p = L; Polynomial* q = S->next; //q为S的第一个节点
    int i;
    for (i = 1; i <= PolynLength(L); i++)
        p = p->next;  //p为L的最后一个节点
    p->next = q; 
    printf("连接成功\n");
}

int compare(int a, int b)
{
	if (a < b)
		return -1;
	else if (a == b)
		return 0;
	else
		return 1;
}
  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值