利用链表实现一元多项式的加减乘,本次实验采用的头文件与源文件分离的方式。本篇文章将只截取函数与主函数,对于头文件与源文件的用法自行查询。
目录
4.通用的函数(创建,排序,输出,释放)放在其他函数前面,避免声明的问题
1.加法实现
PNODE addPoly(PNODE polyAddLeft, PNODE polyAddRight)
{
PNODE headnode = (PNODE)malloc(sizeof(struct node));//创建第三链表
headnode->next = NULL; //用来存放最后结果
PNODE list = headnode;
PNODE l = polyAddLeft->next;//保存第一个链表的结点
PNODE r = polyAddRight->next;//保存第二个链表的结点
PNODE sign=NULL;//sign是用来考虑两个链表系数个数不同的情况
while (l != NULL && r != NULL)
{
if (l->exp == r->exp)//如果指数相同,利用尾插法插入
{
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = l->exp;
temp->coef = l->coef + r->coef;
temp->next = list->next;
list->next = temp;
list = list->next;
l = l->next;
r = r->next;
}
else if (l->exp < r->exp)//由于已经排序的指数是按从小到大,so如果指数相同一开始必然对应,当小于且不同时证明已经没有相同的了,直接存 ,并跳转下一个节点
{
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = l->exp;
temp->coef = l->coef;
temp->next = list->next;
list->next = temp;
list = list->next;
l = l->next;
}
else
{//同理,如果1链表大于2链表,则证明2链表结点此时最小,也直接存
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = r->exp;
temp->coef = r->coef;
temp->next = list->next;
list->next = temp;
list = list->next;
r = r->next;
}
if (l == NULL) sign = r;//如果l比r系数多就把r存进去 ,此时sign就相当于一个r结点开始的链表
if (r == NULL) sign = l;
}
while (sign != NULL)
{
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = sign->exp;
temp->coef = sign->coef;
temp->next = list->next;
list->next = temp;
list = list->next;
sign = sign->next;
}
return headnode;
}
2.减法实现
//减法,基本和加法一样
PNODE minusPoly(PNODE polyminusLeft, PNODE polyminusRight)
{
PNODE headnode = (PNODE)malloc(sizeof(struct node));//创建第三链表,用来存放最后结果
headnode->next = NULL;
PNODE list = headnode;
PNODE l = polyminusLeft->next;//保存第一个链表的结点
PNODE r = polyminusRight->next;//保存第二个链表的结点
PNODE sign = NULL;//sign是用来考虑两个链表系数个数不同的情况
int k = 0;//判断是哪个链表系数多,来判断存放的正负
while (l != NULL && r != NULL)
{
if (l->exp == r->exp)//如果指数相同,利用尾插法插入
{
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = l->exp;
temp->coef = l->coef - r->coef;
temp->next = list->next;
list->next = temp;
list = list->next;
l = l->next;
r = r->next;
}
else if (l->exp < r->exp)//由于已经排序的指数是按从小到大,so如果指数相同一开始必然对应,当小于且不同时证明已经没有相同的了,直接存 ,并跳转下一个节点
{
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = l->exp;
temp->coef = l->coef;
temp->next = list->next;
list->next = temp;
list = list->next;
l = l->next;
}
else
{//同理,如果1链表大于2链表,则证明2链表结点此时最小,也直接存,但此时存的是负数
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = r->exp;
temp->coef = 0-r->coef;//一个0来减去就成了相反的数
temp->next = list->next;
list->next = temp;
list = list->next;
r = r->next;
}
if (l == NULL)
{
sign = r;
k = 1;
}//如果l比r系数多就把r存进去 ,此时sign就相当于一个r结点开始的链表,而且要变负数
if (r == NULL)
{
sign = l;
k = 0;
}//不要变负数
}
if (k == 0)
{
while (sign != NULL)
{
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = sign->exp;
temp->coef = sign->coef;
temp->next = list->next;
list->next = temp;
list = list->next;
sign = sign->next;
}
}
else {
while (sign != NULL)
{
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = sign->exp;
temp->coef = 0-sign->coef;
temp->next = list->next;
list->next = temp;
list = list->next;
sign = sign->next;
}
}
return headnode;
}
3.乘法实现
PNODE mupPoly(PNODE polymupLeft, PNODE polymupRight)
{
PNODE headnode = (PNODE)malloc(sizeof(struct node));//创建第三链表,用来存放最后结果
headnode->next = NULL;
PNODE list = headnode;
PNODE l = polymupLeft->next;//保存第一个链表的结点
PNODE r = polymupRight->next;//保存第二个链表的结点
while (l != NULL)//以第一个多项式为乘法的前列,就是乘数
{
while (r != NULL)//相乘数
{
PNODE p = headnode->next;
PNODE temp = (PNODE)malloc(sizeof(struct node));
temp->exp = l->exp+r->exp;
temp->coef = l->coef * r->coef;
while (p != NULL)//遍历比较三链表
{
if (p->exp == temp->exp)
{
p->coef = p->coef + temp->coef;
goto A;//goto语句一般不要用,但当要跳出多层嵌套语句的时候可以适当使用
} //就像现在,如果第三个链表里已经有指数相同的结点了,就不用新插入一个,直接加在原有结点就可以
p = p->next;
}
temp->next = list->next;//尾插法
list->next = temp;
list = list->next;
A: r = r->next;
}
l = l->next;
r = polymupRight->next;//回到第一个结点
}
return headnode;
}
4.通用的函数(创建,排序,输出,释放)(放在其他函数前面,避免声明的问题)
PNODE createPoly(int num)
{
int c;
int e;
PNODE headnode = (PNODE)malloc(sizeof(struct node));//头结点
headnode->next = NULL;
PNODE list = headnode;
for (int i = 1; i <= num; i++)
{
printf("第%d个系数:",i);
scanf("%d", &c);
printf("第%d个指数:", i);
scanf("%d", &e);
printf("\n");
PNODE newnode;//创建新节点
newnode = (struct node*)malloc(sizeof(struct node));
newnode->coef = c;
newnode->exp = e;
// 利用尾插法
newnode->next = list->next;
list->next = newnode;
list = list->next;
}
return headnode;
}
void printPoly(PNODE poly)
{
PNODE list = poly->next;
printf("最后结果是:");
while (list != NULL)
{
if (list->coef != 0)
{
if (list != poly->next && list->coef > 0)
{
printf("+");
}
if (list->coef == 1)
{
printf("x^%d", list->exp);
}
else if (list->coef == -1)
{
printf("-x^%d", list->exp);
}
else
{
printf("%dx^%d", list->coef, list->exp);
}
}
list = list->next;
}
}
void destroyPoly(PNODE poly)//释放链表要一个节点一个节点的释放
{
PNODE list = poly;
PNODE m;
while (list != NULL)
{
m = list;
list = m->next;
free(m);
}
}
void sortPoly(PNODE poly)//排序
{
int i, num,count=0;//count记录链表结点的个数,num进行内层循环,
PNODE p, q, tail;//创建三个指针,进行冒泡排序
p = poly;
while (p->next != NULL)//计算出结点的个数
{
count++;
p = p->next;
}//如果只做加减,这里的count是已知的,如果做乘法的同时直接排序了,就可以无需调用sort
for (i = 0; i < count - 1; i++)//外层循环,跟数组冒泡排序一样,最多排个数减1次
{
num = count - i - 1;//记录内层循环需要的次数,跟数组冒泡排序一样,排一次下一次的排序少一次
q = poly->next;//令q指向第一个结点
p = q->next;//令p指向后一个结点
tail = poly;//让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作
while (num--)//内层循环 次数跟数组冒泡排序一样
{
if (q->exp > p->exp)//如果该结点的值大于后一个结点,则交换
{
q->next = p->next;
p->next = q;
tail->next = p;
}
tail = tail->next;
q = tail->next;
p = q->next;
}
}
}
5.主函数
#include <stdlib.h>
#include <stdio.h>
struct node
{
int exp; // 表示指数
int coef; //表示系数
struct node* next; //指向下一个结点的指针
};
typedef struct node* PNODE;
int main()
{
PNODE polyLeft, polyRight, polyResult;
B:printf("请输入多项式A的系数个数:");
int num1;
scanf("%d", &num1);
polyLeft=createPoly(num1);
//sortPoly(polyLeft,num1);
sortPoly(polyLeft);
A: printf("请输入多项式B的系数个数:");
int num2;
scanf("%d", &num2);
polyRight = createPoly(num2);
//sortPoly(polyRight,num2);
sortPoly(polyRight);
printf("加法功能请输入1,减法功能请输入2,乘法功能请输入3,\n");
printf("请做出你的选择:");
int n;
scanf("%d", &n);
printf("\n");
if (n == 1)
{
polyResult = addPoly(polyLeft, polyRight);
printPoly(polyResult);
destroyPoly(polyLeft);
destroyPoly(polyRight);;
}
else if (n == 2)
{
int k;
printf("多项式A减多项式B请输入1\n多项式B减多项式A请输入2\n");
printf("请做出你的选择:");
scanf("%d", &k);
if(k==1)polyResult = minusPoly(polyLeft, polyRight);
else polyResult = minusPoly( polyRight , polyLeft );
printPoly(polyResult);
destroyPoly(polyLeft);
destroyPoly(polyRight);
}
else
{
polyResult = mupPoly(polyLeft, polyRight);
sortPoly(polyResult);
printPoly(polyResult);
destroyPoly(polyLeft);
destroyPoly(polyRight);
}
printf("\n");
printf("继续程序请输入1,终止程序请输入2\n");
printf("请做出你的选择:");
scanf("%d", &n);
printf("\n");
if (n == 1)
{
printf("是否沿用本次结果作为多项式A?\n输入1表示继往开来,输入2表示革故鼎新");
printf("请做出你的选择:");
int j;
scanf("%d", &j);
printf("\n");
if (j == 1)
{
polyLeft = polyResult;
goto A;
}
else {
destroyPoly(polyResult);
goto B;
}
}
else {
destroyPoly(polyResult);
return 0;
}
}