C语言一元多项式相加(链表)

今天写一个关于一元多项式相加的程序,就当是在练习运用一下链表的知识。首先,我们先来分析一波,一元多项式相加,首先要用链表创建两个或多个多项式,每个节点里的数据有两个,系数和指数;其次,如果要实现乱幂输入,那么还需要一个排序函数;然后就是多项式相加求和的部分,当指数相等时其系数相加,如果不相等那么就比较大小,依次存入新的链表;最后是输出函数,这个部分也分了很多类型,比如:两式相加为常数(2,4,6)、0、系数为1不显示系数(x,x^4)、指数为1不显示指数(x,2x)等等。

先来定义结构体变量,和单链表的定义结构体一样,不同的是此时我们的数据变成了两个:系数和指数。所以我们这样定义:

typedef struct node{//构造结构体变量 
	
	int coefficient;//定义一个结构体变量“系数” 
	
	int exponent;//定义一个结构体变量“指数”
	
	node *next;
	 
}node;

然后创建单链表来存储第一个多项式的各项式:

node *create(){//尾插法创建单链表 
	
	node *head,*p,*q;
	
	int n;//定义一个整型数据n,用来表示输入的多项式的个数 
	
	int i = 0;//定义一个整型数据i=0,用来表示的输入的第几个多项式的系数或指数 
	
	head = (node*)malloc(sizeof(node));//给head分配内存空间 
	
	head->next = NULL; //先让head为空表 
	
	q = head;//让q等于head的头节点 
	
	printf("你想要输入多少个多项式的数据:");
	
    scanf("%d",&n);
	
	for(i = 0;i < n;i++){
		
		p = (node*)malloc(sizeof(node));//给p分配内存空间 
		
		printf("请输入第%d项的系数:",i+1);
		
		scanf("%d",&p->coefficient);//输入系数 
		
		printf("请输入第%d项的指数:",i+1);
		
		scanf("%d",&p->exponent);//输入指数 
		
		p->next = q->next;
		
		q->next = p;
		
		q = q->next; 
		
	}
	
	return head;
	
}

输出函数,注意这个函数是将两个多项式相加的和已经求出来了进行输出,是把没必要的省略(比如结果为2x^0输出为2),大家看程序就懂了,我就不废话了。

void print(node *head){//输出单链表
	
	node *p;
	
	p = (node*)malloc(sizeof(node));
	
	p = head->next;

	while(p->next != NULL){//如果p的后继节点不为空时执行下列语句 
		
		if(p->coefficient != 0 && p->exponent == 0){//系数不为0指数为0的情况(常数)
		
			printf("%d+",p->coefficient);//所以只输入系数
		
		}
       
       else if(p->coefficient == 1 && p->exponent == 1){//系数为1指数为1的情况 
			
			printf("x+");
			
		}	
		
		else if(p->coefficient != 0 && p->exponent == 1){//系数不为0指数为1的情况(x,2x,5x……) 
		
			printf("%dx+",p->coefficient);//注意前面%d后的x
		
		}
		
		else if(p->coefficient == 1 && p->exponent != 0){//系数为1指数不为0的情况(x^2,x^5……) 
			
			printf("x^%d+",p->exponent);
			
		}
		
		else if(p->coefficient == 0){//两个多项式相加的和为0时的情况,不输出 
			
			printf(""); 
			
		}
		
		else if(p->coefficient != 1 && p->exponent != 0){//系数不为1指数不为0的情况(2x^3,3x^2……) 
			
			printf("%dx^%d+",p->coefficient,p->exponent);
			
		}
		
		p = p->next;//让p等于它的后继结点,继续循环
	}

	if(p->exponent == 0 && p->coefficient != 0){//判断最后一个多项式的类型 (ps:因为上述循环当中我们定义p->next!=NULL时执行,那么当p为最后一个结点时,p->next已经是空了,那么这个时候就会跳出循环,最后一个结点的数据就会不运行出来,所以我们需要另写,如果不想写这么多代码的话让它在循环内输出也很简单,大家可以动脑筋想一想),下列语句同上 
		
			printf("%d",p->coefficient);
		
		}	

        else if(p->coefficient == 1 && p->exponent == 1){//系数为1指数为1的情况 
			
			printf("x+");
			
		}
		
		else if(p->exponent == 1 && p->coefficient != 0){
		
			printf("%dx",p->coefficient);
		
		}
		
		else if(p->coefficient == 1 && p->exponent != 0){
			
			printf("x^%d",p->exponent);
			
		}
		
		else if(p->coefficient == 0){
			
			printf("0"); //这条语句和上面不一样,因为这是最后一个多项式的输出,如果最后一个多项式的计算结果为0,那么不这样写就会输出(……+)有一个加号,不美观
			
		}
		
		else if(p->coefficient != 1 && p->exponent != 0){
			
			printf("%dx^%d",p->coefficient,p->exponent);
			
		}

}

然后就是排序,注意这个排序是将还未执行求和函数的两个多项式进行升幂排序,然后进行相加。(不是已经求和之后进行升幂排序)

void paixu(node *head){//将多项式按升幂排序 
	
	node *p,*q;
	
	int temp,temp1;
	
	for(p=head->next;p!=NULL;p=p->next){//运用了两个for循环
		
		for(q=p->next;q!=NULL;q=q->next){//q为p的后继结点
			
			if(p->exponent > q->exponent){//如果p的指数比q的指数大,也就是前一项的指数比后一个指数大,那么交换它们的指数和系数
			
				temp = p->exponent;
			
				p->exponent = q->exponent;
			
				q->exponent = temp;
			
				temp1 = p->coefficient;
			
				p->coefficient = q->coefficient;
			
				q->coefficient = temp1;
			
			}
		} 
	}
} 

最后是多项式相加

node *add(node *&head1,node *head2){//一元多项式相加 (将一元多项式相加的结果存放在head1中) 
	
	node *a,*b,*p;
	
	a = head1->next;
	
	b = head2->next;
	
	p = head1;
	
	while(a != NULL && b != NULL){
		
		if(a->exponent == b->exponent){
			
			a->coefficient = a->coefficient+b->coefficient;
			
			p->next = a;

			p = p->next;
			
			a = a->next;
			
			b = b->next;
			
		}
		
		else if(a->exponent < b->exponent){
			
			p->next = a;
			
			p = p->next;
			
			a = a->next;
			
		}
		
		else{
			
			p->next = b;
			
		    p = p->next;
		    
		    b = b->next;
			
		}
		
	}
	
	if(a != NULL){//比较结束之后a或b如果有一个还未空就执行下述语句
			
			p->next = a;
			
		}
		
		else{
			
			p->next = b;
			
	    }
	
	return head1;
	
}

最后主函数

int main(){
	
	node *head1,*head2,*h;
	
	head1 = create();//创建第一个多项式
	
	head2 = create();//创建第二个多项式

	paixu(head1);//将第一个多项式按升幂排序
	
	paixu(head2);//同上
	
	h = add(head1,head2);//相加

	print(h);//输出

    return 0;

}

然后一个多项式相加的代码就完成了,在写博客的过程中突然发现自己相加和输出函数有一些问题,就顺便改正了,不得不说这写博客真的好处多多啊,还有就是输出函数里的分类没有完整,因为有系数为负数的情况,我懒得写了,大家有兴趣的可以写一写,不难的,就是简单的判断语句。

哦!还缺一个头文件

#include
#include

这就完美了。

最后奉上一个运行结果
C语言一元多项式相加(链表)_第1张图片
这是vscode的运行结果

上述程序依次写入Dev-C++和vscode以及vs2019中都可以执行,但如果是vs2019里其scanf要改为scanf_s,因为这是vs2019的编译规则,而且还可能出现警告(取消NULL指针对P的调用),这个问题的解决大家可以看我的第一个博客里有解决方法,这里就不多说了。

最后,就希望路过的大佬可以给一点建议,还有就是希望和我一样的编程小白可以一起努力!

你可能感兴趣的:(链表,算法,c语言)