多项式相加的算法,C实现

目录

题目

代码

1.全部代码

2.头文件和宏定义

3.主函数

4.核心函数

5.辅助函数

5.1建立新结点

5.2建立带头结点的链表(此算法中是多项式)

5.3.建立完整的多项式(输入)

5.4打印多项式

5.5其他简单函数

说明


题目

将多项式Pa和Pb合并,并以Pa返回,同时删除Pb

代码

1.全部代码

#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0

typedef int Status;
typedef struct
{//项的表示
	float coef;//系数
	int expn;//指数
}ElemType;//声明数据元素结构布局
typedef struct LNode
{
	ElemType data;
	struct LNode* next;
}LNode, * Link, * Position;//声明结点结构布局
typedef struct
{
	Link head, tail;
}LinkList;
typedef LinkList Polynomial;//将带头结点的链表定义为多项式

void SetCurElem(Link, ElemType);
Status MakeNode(Link*, ElemType);
Status InitPolyn(Polynomial*);
Status CreatePolyn(Polynomial*);
void PrintPolyn(Polynomial);
void AddPolyn(Polynomial*, Polynomial*);
int cmp(ElemType, ElemType);
Position GetHead(Polynomial);
Position GetLast(Polynomial);
Position NextPos(Link);
ElemType GetCurElem(Link);
void DelFirst(Link, Link*);
void InsFirst(Link, Link);
void Append(Polynomial*, Link);//tail指针改变了,希望得到这种改变
void FreeNode(Link);

int main()
{
	Polynomial Pa, Pb;
	CreatePolyn(&Pa);
	CreatePolyn(&Pb);
	printf("Output Pa:\n");
	PrintPolyn(Pa);
	printf("\nOutput Pb:\n");
	PrintPolyn(Pb);
	AddPolyn(&Pa, &Pb);
	printf("\nResult Pa:\n");
	PrintPolyn(Pa);
	return 0;
}
//1.将p所指结点的数据元素设置为e
void SetCurElem(Link p, ElemType e)
{
	p->data.coef = e.coef;
	p->data.expn = e.expn;
}
//2.用指针p承接动态分匹配的结点的地址,并将数据元素设置为e
Status MakeNode(Link* pp, ElemType e)
{
	*pp = (Link)malloc(sizeof(LNode));
	if (!*pp)return ERROR;
	SetCurElem(*pp, e);
	(*pp)->next = NULL;
	return OK;
}
//3.建立带头结点的链表(多项式)
Status InitPolyn(Polynomial* pP)
{
	ElemType e = { 0.0,-1 };
	MakeNode(&pP->head, e);
	if (!pP->head)return ERROR;
	pP->tail = pP->head;//tial是尾指针,初始化
	return OK;
}
//4.建立完整的链表
Status CreatePolyn(Polynomial* pP)
{
	InitPolyn(pP);
	Link p;
	ElemType e;
	int i, n;
	printf("enter the number of Polyn:\n");
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		printf("enter coef,expn:\n");
		scanf("%f,%d", &e.coef, &e.expn);
		MakeNode(&p, e);//建立新结点
		if (!p)return ERROR;
		pP->tail->next = p;
		pP->tail = p;//更新尾指针
	}
	return OK;
}
//5.打印多项式
void PrintPolyn(Polynomial P)
{
	Link p, h = GetHead(P);
	p = NextPos(h);
	int k = 0;//表示项的位置
	ElemType e;
	while (p)
	{
		e = GetCurElem(p);
		printf("%dth %5.2fx[%d]\n", ++k, e.coef, e.expn);
		p = NextPos(p);
	}
	printf("--------Print finished-------");
}
//6.多项式相加
void AddPolyn(Polynomial* pPa, Polynomial* pPb)
{
	Link ha, hb, pa, pb, prev, q;//prev记录pa前一个结点的位置
	ElemType a, b;
	float sum = 0.0;
	ha = GetHead(*pPa); hb = GetHead(*pPb);
	pa = NextPos(ha); pb = NextPos(hb);
	prev = ha;
	while (pa && pb)
	{
		a = GetCurElem(pa); b = GetCurElem(pb);
		switch (cmp(a, b))
		{
		case -1://a的指数小,不对多项式Pb操作
		{
			prev = pa; pa = NextPos(pa); break;
		}
		case 0:
		{
			sum = a.coef + b.coef;
			if (sum)//系数非0,更改Pa的系数,对地址操作!
			{
				pa->data.coef=sum; prev = pa;//a.coef=sum错
			}
			else//系数为0,删除pa所指结点,同时更新pa(之后统一),prev
			{
				DelFirst(prev, &pa); FreeNode(pa);
				if (pa == GetLast(*pPb))pPb->tail = prev;//注意尾指针所指结点可能被删除了
														//及时更改尾指针
			}
			DelFirst(hb, &q);FreeNode(q);//删除Pb当前结点
			pa = NextPos(prev); pb = NextPos(hb); break;
		}
		case 1://a的指数大,将多项式Pb当前结点插入Pa当前结点之前
		{
			DelFirst(hb, &q);
			InsFirst(prev, q);
			pb = NextPos(hb); pa = NextPos(pa);
		}
		}
	}
	if (pb)
	{
		Append(pPa, pb);//注意Append函数和InsFirst函数的区别
		pPa->tail = pPb->tail;
	}
	FreeNode(hb);
}
//7.获得头指针
Position GetHead(Polynomial P)
{
	return P.head;
}
//8.获得尾指针
Position GetLast(Polynomial P)
{
	return P.tail;
}
//9.指针p后移一位
Position NextPos(Link p)
{
	return p->next;
}
//10.获得当前数据元素
ElemType GetCurElem(Link p)
{
	return p->data;
}
//11.比较指数大小
int cmp(ElemType a, ElemType b)
{
	return(a.expn == b.expn ? 0 : (a.expn > b.expn ? 1 : -1));
}
//12.删除指针h所指结点的后一个结点
void DelFirst(Link h, Link* pq)
{
	*pq = NextPos(h);
	h->next = NextPos(*pq);
}
//13.指针s所指结点插入p所指结点后
void InsFirst(Link p, Link s)
{
	s->next = NextPos(p);
	p->next = s;
}
//14.将指针p所指结点(及之后的结点)链接在多项式后
void Append(Polynomial* pP, Link p)
{
	pP->tail->next = p;
}
//15.释放指针p所指结点内存
void FreeNode(Link p)
{
	free(p);
}

2.头文件和宏定义

#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0

typedef int Status;
typedef struct
{//项的表示
	float coef;//系数
	int expn;//指数
}ElemType;//声明数据元素结构布局
typedef struct LNode
{
	ElemType data;
	struct LNode* next;
}LNode, * Link, * Position;//声明结点结构布局
typedef struct
{
	Link head, tail;
}LinkList;
typedef LinkList Polynomial;//将带头结点的链表定义为多项式

void SetCurElem(Link, ElemType);
Status MakeNode(Link*, ElemType);
Status InitPolyn(Polynomial*);
Status CreatePolyn(Polynomial*);
void PrintPolyn(Polynomial);
void AddPolyn(Polynomial*, Polynomial*);
int cmp(ElemType, ElemType);
Position GetHead(Polynomial);
Position GetLast(Polynomial);
Position NextPos(Link);
ElemType GetCurElem(Link);
void DelFirst(Link, Link*);
void InsFirst(Link, Link);
void Append(Polynomial*, Link);//tail指针改变了,希望得到这种改变
void FreeNode(Link);

3.主函数

int main()
{
	Polynomial Pa, Pb;
	CreatePolyn(&Pa);
	CreatePolyn(&Pb);
	printf("Output Pa:\n");
	PrintPolyn(Pa);
	printf("\nOutput Pb:\n");
	PrintPolyn(Pb);
	AddPolyn(&Pa, &Pb);
	printf("\nResult Pa:\n");
	PrintPolyn(Pa);
	return 0;
}

4.核心函数


//多项式相加
void AddPolyn(Polynomial* pPa, Polynomial* pPb)
{
	Link ha, hb, pa, pb, prev, q;//prev记录pa前一个结点的位置
	ElemType a, b;
	float sum = 0.0;
	ha = GetHead(*pPa); hb = GetHead(*pPb);
	pa = NextPos(ha); pb = NextPos(hb);
	prev = ha;
	while (pa && pb)
	{
		a = GetCurElem(pa); b = GetCurElem(pb);
		switch (cmp(a, b))
		{
		case -1://a的指数小,不对多项式Pb操作
		{
			prev = pa; pa = NextPos(pa); break;
		}
		case 0:
		{
			sum = a.coef + b.coef;
			if (sum)//系数非0,更改Pa的系数,对地址操作!
			{
				pa->data.coef=sum; prev = pa;//a.coef=sum错
			}
			else//系数为0,删除pa所指结点,同时更新pa(之后统一),prev
			{
				DelFirst(prev, &pa); FreeNode(pa);
				if (pa == GetLast(*pPb))pPb->tail = prev;//注意尾指针所指结点可能被删除了
														//及时更改尾指针
			}
			DelFirst(hb, &q);FreeNode(q);//删除Pb当前结点
			pa = NextPos(prev); pb = NextPos(hb); break;
		}
		case 1://a的指数大,将多项式Pb当前结点插入Pa当前结点之前
		{
			DelFirst(hb, &q);
			InsFirst(prev, q);
			pb = NextPos(hb); pa = NextPos(pa);
		}
		}
	}
	if (pb)
	{
		Append(pPa, pb);//注意Append函数和InsFirst函数的区别
		pPa->tail = pPb->tail;
	}
	FreeNode(hb);
}

5.辅助函数

5.1建立新结点

//1.将p所指结点的数据元素设置为e
void SetCurElem(Link p, ElemType e)
{
	p->data.coef = e.coef;
	p->data.expn = e.expn;
}
//2.用指针p承接动态分匹配的结点的地址,并将数据元素设置为e
Status MakeNode(Link* pp, ElemType e)
{
	*pp = (Link)malloc(sizeof(LNode));
	if (!*pp)return ERROR;
	SetCurElem(*pp, e);
	(*pp)->next = NULL;
	return OK;
}

5.2建立带头结点的链表(此算法中是多项式)

//3.建立带头结点的链表(多项式)
Status InitPolyn(Polynomial* pP)
{
	ElemType e = { 0.0,-1 };
	MakeNode(&pP->head, e);
	if (!pP->head)return ERROR;
	pP->tail = pP->head;//tial是尾指针,初始化
	return OK;
}

5.3.建立完整的多项式(输入)

//4.建立完整的链表
Status CreatePolyn(Polynomial* pP)
{
	InitPolyn(pP);
	Link p;
	ElemType e;
	int i, n;
	printf("enter the number of Polyn:\n");
	scanf("%d", &n);
	for (i = 0; i < n; i++)
	{
		printf("enter coef,expn:\n");
		scanf("%f,%d", &e.coef, &e.expn);
		MakeNode(&p, e);//建立新结点
		if (!p)return ERROR;
		pP->tail->next = p;
		pP->tail = p;//更新尾指针
	}
	return OK;
}

5.4打印多项式

//5.打印多项式
void PrintPolyn(Polynomial P)
{
	Link p, h = GetHead(P);
	p = NextPos(h);
	int k = 0;//表示项的位置
	ElemType e;
	while (p)
	{
		e = GetCurElem(p);
		printf("%dth %5.2fx[%d]\n", ++k, e.coef, e.expn);
		p = NextPos(p);
	}
	printf("--------Print finished-------");
}

5.5其他简单函数

//7.获得头指针
Position GetHead(Polynomial P)
{
	return P.head;
}
//8.获得尾指针
Position GetLast(Polynomial P)
{
	return P.tail;
}
//9.指针p后移一位
Position NextPos(Link p)
{
	return p->next;
}
//10.获得当前数据元素
ElemType GetCurElem(Link p)
{
	return p->data;
}
//11.比较指数大小
int cmp(ElemType a, ElemType b)
{
	return(a.expn == b.expn ? 0 : (a.expn > b.expn ? 1 : -1));
}
//12.删除指针h所指结点的后一个结点
void DelFirst(Link h, Link* pq)
{
	*pq = NextPos(h);
	h->next = NextPos(*pq);
}
//13.指针s所指结点插入p所指结点后
void InsFirst(Link p, Link s)
{
	s->next = NextPos(p);
	p->next = s;
}
//14.将指针p所指结点(及之后的结点)链接在多项式后
void Append(Polynomial* pP, Link p)
{
	pP->tail->next = p;
}
//15.释放指针p所指结点内存
void FreeNode(Link p)
{
	free(p);
}

​

说明

这个是《数据结构(C语言版)》严蔚敏里的算法,C代码实现。学习记录p43

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值