大家好,我是小白莲,今天小白莲给大家介绍的是用有序链表实现一元多项式的加法
主要思想:
设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;
}
当然,如果觉得小白莲写得还不错,记得一定!一定!要点个赞再走哦!最好关注一下也是可以的,你们的对我的点赞和关注就是对我最大的支持,我真的很需要,谢谢!说的就是你,光收藏却不点赞,哼~~
给人点赞,手留余香
预知后续操作如何,请看下集
@author 白莲居仙 QQ:1131977233