一元多项式的加法详解

一元多项式的加法(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;
}
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值