一元多项式的加法(c语言版)
我是观看懒猫老师的视频后写的,大家有不懂的可以在评论区留言或者去某站看懒猫老师的视频
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//定义每个元素的结构
typedef struct polynomial
{
int coefficient;//系数
int exp;//指数
struct polynomial *next;
}*Link,Node;
void inputPoly(Link head);//用于从控制台读入链表的函数
void print(Link head);//打印链表用的函数
bool insert(Link head,int coefficient,int exp);//向链表插入一个元素的函数
void combin2List(Link heada,Link headb,Link headab);//合并两个链表
int main()
{
Link headA,headB;//两个多项式的头指针
Link headAB;//合并后的多项式的头指针
/*链表的初始化 创建头结点*/
headA=(Link)malloc(sizeof(Node));
headA->next=NULL;
headB=(Link)malloc(sizeof(Node));
headB->next=NULL;
headAB=(Link)malloc(sizeof(Node));
headAB->next=NULL;
printf("请输入第一个多项式的系数和指数,以(0 0)结束:\n");
inputPoly(headA);
printf("第一个");
print(headA);
printf("请输入第二个多项式的系数和指数,以(0 0)结束:\n");
inputPoly(headB);
printf("第二个");
print(headB);
combin2List(headA,headB,headAB);
printf("合并后");
print(headAB);
return 0;
}
/**输入二项式数据的函数*/
/*这个函数用来输入二项式,给用户合适的提示,读入用户输入的系数和指数。
调用函数insert,将用户输入的二项式的一项插入到链表中去。*/
void inputPoly(Link head)
{
int coefficient,exp;//系数和指数
printf("请输入系数和指数(如:\"2 3\"表示2x^3):");
scanf("%d %d",&coefficient,&exp);
while(coefficient!=0||exp!=0)//连续输入多个系数和指数
{
insert(head,coefficient,exp);//调函数输入多项式
// head->next->exp;
printf("请输入系数和指数:");
scanf("%d %d",&coefficient,&exp);
}
}
/**向多项式链表中插入元素的函数
int coefficient 一个多项式项的系数
int exp 一个多项式项的幂
*/
bool insert(Link head,int coefficient,int exp)
{
Link node; //node指针指向新创建的节点
Link q,p; //q,p两个节点一前一后
//创建一个新结点
node =(Link)malloc(sizeof(Node));
node->coefficient=coefficient;
node->exp=exp;
node->next=NULL;
p=head->next;
q=head;
if(head->next==NULL)//空表,插第1个
{
head->next=node;
}
else
{
while(p != NULL){ //循环访问链表中的所有节点
//p->coefficient;
//p->exp;
//如果node节点的指数比p节点的指数大,则插在p的前面,完成插入后,提前退出
if(p->exp < node->exp){
node->next=q->next;
q->next=node;
node=NULL;
free(node);
return true;
}
//如果node节点的指数和p节点的指数相等,则合并这个多项式节点,提前退出
else if(p->exp==node->exp){
p->coefficient=p->coefficient+node->coefficient;
free(node);
return true;
}
//如果node节点的指数比p节点的指数小,继续向后移动指针(依然保持p,q一前一后)
else if(node->exp<p->exp){
q=p;
p=p->next;
}
}
//如果退出循环是当前指针p移动到链表结尾,则说明之前没有插入,那么当前node节点的指数值是最小值,此时插在链表的最后面
q->next=node;
node=NULL;
free(node);
}
return true;
}
/*
打印多项式链表的函数
*/
void print(Link head)
{
Link p; //指向链表要输出的结点
printf("多项式如下:\n");
p=head->next; //指向第一个有效节点
if (p == NULL)
{
printf("多项式为空\n");
return;
}
// 不是空表
bool isFirstItem=true;//标志是否为第一个节点的flag
//打印节点
do {
//第一步判断符号
//如果是第一项,不用打符号 即为空语句
//如果不是第一项
if(!isFirstItem){
if(p->coefficient>0){//系数为正数
printf("+");//要打加号
}
//如果系数为负数,系数自身带有负号也不用打符号
}
//第二步判断系数 (只写需要打印的代码,不用打印的内容不用写)
//1和-1比较特殊(指定情况下可以省略)
if(p->exp==0){//指数为0
if(p->coefficient==1){//系数为1
printf("1");//输出1
}
else if(p->coefficient==-1){//系数为-1
printf("-1");//输出-1
}
}
//指数不为0 系数为-1(如:-x) 只打印负号
if(p->coefficient==-1&&p->exp!=0){
printf("-");
}
//如果系数不为1或-1或0,打印系数
else if(p->coefficient!=1&&p->coefficient!=-1&&p->coefficient!=0){//注意系数这部分始终没有输出过1或-1
printf("%d",p->coefficient);
}
//只有当指数为0时不用打印x 和 指数
//判断x 和 指数
if(p->exp!=0&&p->coefficient!=0){
printf("x");//打印x 的条件 指数不为0且系数不为0
if(p->exp!=1){
printf("^%d",p->exp);// 打印指数的条件 指数不为0和1 且系数不为0
}
}
if(p->coefficient!=0){
isFirstItem=false; //flag标志不是第一项了
}
p = p->next;//指向下个结点
}while(p != NULL);
printf("\n");
return;
}
/* 合并两个有序链表a,b到链表ab
heada.headb,headab分别为链表a,b,ab的头指针 */
void combin2List(Link heada,Link headb,Link headab){
Link pa,pb,pab;//指向a,b链表和ab的指针
pa=heada->next;
pb=headb->next;
pab=headab;
while(pa!=NULL&&pb!=NULL)//a,b链表都没有没有访问完毕
{
//如果指数a>指数b,a节点插入ab链表,a指针后移
if(pa->exp>pb->exp){
pab->next=pa;
pab=pab->next;
pa=pa->next;
pab->next=NULL;
}
//如果指数a<指数b,b节点插入ab链表,b指针后移
else if(pa->exp<pb->exp){
pab->next=pb;
pab=pab->next;
pb=pb->next;
pab->next=NULL;
}
//如果指数a==指数b,a、b系数相加,插入ab链表,a、b指针后移
else if(pa->exp==pb->exp){
pa->coefficient=pa->coefficient+pb->coefficient;
pab->next=pa;
pab=pab->next;
pa=pa->next;
pb=pb->next;
pab->next=NULL;
}
}
//如果a、b链表还有尾巴,将它加到ab链表后面
if(pa!=NULL) {
free(headb);
free(pb);
pab->next=pa;
free(heada);
pa=NULL;
free(pa);
}
if(pb!=NULL) {
free(heada);
free(pa);
pab->next=pb;
pb=NULL;
free(pb);
free(headb);
}
return;
}