数据结构学习记录(6)——多项式相加(链表实现)

思路:(1)指数相同项对应系数相加,若和不为0,构成多项式中的一项

           (2)因为输入多项式无序所以应该先排序后相加

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h> 
struct node{
	float x1;
	int x2;//分别存储小数与整数部分
	node *next; 
}; 
//创建函数部分(尾插法) 
node *creat(){
	node *p,*pre,*head;
	float x1;int x2;int x3;//贮存第一个数据 
	int count=0;//记录输入次数 
	bool n=false;
	head = (node*)malloc(sizeof(node));
	pre=head;
	while(1){
		if(n==false){
			scanf("%d",&x3);
			n=true;
			continue;
		}
		if(count<x3){
			scanf("%f %d",&x1,&x2);
			p = (node*)malloc(sizeof(node));
			p->x1=x1;
			p->x2=x2;
			pre->next=p;
			pre=p;
			count++; 
			continue;
		}
		if(count==x3) break;
	} 
	pre->next=NULL;//表示结束 
	return head;
} 
//无序的两个链表变为降序排列(冒泡排序法) 
void swap(int *x1,int *x2){
	int temp;
	temp=*x1;
	*x1=*x2;
	*x2=temp;
	
}
void swap1(float *x1,float *x2){
	float temp;
	temp=*x1;
	*x1=*x2;
	*x2=temp;
	
}
node *sort(node *poly){
	if(poly==NULL||poly->next==NULL) return poly;
	node *p=NULL;
	bool inChange=true;
	while(poly->next!=p&&inChange)//每次循环次数减1
	{
		 node *q = poly->next;
         inChange = false;//标志当前这一轮中又没有发生元素交换,如果没有则表示数组已经有序
            for(; q->next && q->next != p; q = q->next)//q->next!=q每次循环次数减一 
            {
                if(q->x2 < q->next->x2)
                {
                    swap(&q->x2, &q->next->x2);
                    swap1(&q->x1, &q->next->x1);
                    inChange = true;
                }
            }
            p = q;
	}
	return poly;
}
//多项式相加 两个多项式相加,和多项式放于polya中,并删除polyb 
node *polyAdd(node *polya,node *polyb){
	node *a,*b,*tail,*temp;
	float sum;
	a=polya->next;
	b=polyb->next;
	tail=polya;//tail表示尾结点向后插入数据需添加前置结点该处tail,可根据尾插法pre理解 
	while(a!=NULL&&b!=NULL){
		if(a->x2 > b->x2){
			tail->next=a;//若不等,a向后移动 
			tail=a;
			a=a->next;
		}
		else if(a->x2==b->x2){
			sum = a->x1+b->x1;//指数相等系数相加 
			if(sum!=0){
				a->x1=sum;
				tail->next=a;
				tail=a;
				a=a->next;
				temp=b;
				b=b->next;
				free(temp);
			}
			else//相加为0释放a与b 
			{
				temp=a;a=a->next;free(temp);
				temp=b;b=b->next;free(temp);
			}
		}
		//将b中剩余结点加至a中 
		else{
			tail->next=b;tail=b;b=b->next; 
		} 
	}
	//若有剩余将剩余结点加入和多项式 
	if(a!=NULL)
	tail->next=a;//因为前方链表已经被释放内存所以可直接相连
	else
	tail->next=b;
	return polya; 
} //free(polyb)**疑问此处报错与书中内容不符**
//比对输出 
void search(node *L,int n) {
	node *p = L->next;
	int count;//记录遍历次数
	for(count=1;count<n;count++) {
		p = p->next;
	} 
	printf("%.1f %d",p->x1,p->x2);
}
//主函数部分
int main () {
	int N;
	node *polya=creat();
	node *polyb=creat();
	scanf("%d",&N);
	//无序变降序 
	node *polys_a=sort(polya);
	node *polys_b=sort(polyb);
	//polys_a=polys_a->next;
	node *polyadd=polyAdd(polys_a,polys_b);
	/*while(polys_a!=NULL){
		printf("%d ",polys_a->x2);
		polys_a=polys_a->next;
	}*/
	/*while(polyadd!=NULL){
		printf("%.1f %d ",polyadd->x1,polyadd->x2);
		polyadd=polyadd->next;
	}*/
	search(polyadd,N); 
	return 0;
} 
/*4 1.2 3 4.5 6 2.1 4 9.2 7
3 0.2 6 -4.5 9 -2.1 4*/

链表排序方法链接:链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序) - tenos - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值