链表实现多项式加法与乘法

链表实现加法与乘法

构建一个链表

typedef struct LinkNode{
    
    
	int coef;//系数
	int expn;//幂指数
	LinkNode *next; 
}LinkNode,*LinkList;

为了使得直接可以更好的查看输出结果,顺便写一个show函数用来展示结果

void show(LinkList L){
    
    //输出多项式链表结点; 
	if(L==NULL||L->next==NULL){
    
    
		printf("0 0\n");
		return;
	}
	LinkNode *r=L->next;
	while(r->next){
    
    
		printf("%d %d ",r->coef,r->expn);
		r=r->next;
	}
	printf("%d %d\n",r->coef,r->expn);
} 

现在我们来考虑多项式的加法怎么实现:
首先我们假定输入的多项式都是按幂次升序排列输入的,然后将多项式中的一个单项式拿出来,然后将其系数和幂次作为两个数据传入链表当中。因为word作图不方便我就直接手画了(字丑勿喷):
在这里插入图片描述
然后我们对两个链表进行比较,比较幂次部分是否相同,如果不同,把幂次小的的先插入新链表,如果幂次相同,则对系数部分进行加减法,这时候要判断一下结果是否为零,如果结果为零,直接丢弃这个结点,然后依次遍历下去直到两个链表都遍历结束。(这里的插入结点到新链表部分我就不写了哦!)

LinkList  Listadd(LinkList L1,LinkList L2){
    
    
	LinkNode *front=(LinkNode *)malloc(sizeof(LinkNode));
	LinkNode *rear=front;
	front->next=NULL;
	int co,ex;//系数与幂指数; 
	LinkNode *r1=L1->next,*r2=L2->next;
	if(r1==NULL&&r2==NULL) return NULL;
	while(r1&&r2){
    
    //当两个链表不为空的时候; 
		if(r1->expn==r2->expn){
    
    
			co=r1->coef+r2->coef;
			if(co!=0){
    
    
				ex=r1->expn;
				attach(co,ex,rear);
			}
			r1=r1->next;
			r2=r2->next;
		}
		else if(r1->expn<r2->expn){
    
    
			attach(r1->coef,r1->expn,rear);
			r1=r1->next;
		}
		else{
    
    
			attach(r2->coef,r2->expn,rear);
			r2=r2->next;
		}
	}
	while(r1){
    
    
		attach(r1->coef,r1->expn,rear);
		r1=r1->next;
	}
	while(r2){
    
    
		attach(r2->coef,r2->expn,rear);
		r2=r2->next;
	}
	rear->next=NULL;
	return front;
}

这样我们加法就结束了。

乘法 (难点哦!)

按照我们正常的思维习惯肯定是循环遍历两个链表,然后对于两个链表中的结点都进行一次乘法运算,然后使用其中一个链表长度大小值的个数个新链表存储。用途表示就是这样:
在这里插入图片描述
但是有没有感觉我们浪费了太多内存来存储呢?所以我们可以使用直接在上一次存储的新链表中继续操作,就是找一个适合的结点插入新得到的结果咯
所以我们有:

LinkList ListMultiply(LinkList L1,LinkList L2){
    
    
	LinkNode *front=(LinkNode *)malloc(sizeof(LinkNode));
	LinkNode *rear=front;
	front->next=NULL;
	int co,ex;//系数与幂指数; 
	LinkNode *r1=L1->next,*r2=L2->next;
	if(r1==NULL||r2==NULL) return NULL;
	//先用L1第一个结点与L2乘一次; 
	while(r2){
    
    
		co=r2->coef*r1->coef;
		ex=r2->expn+r1->expn;
		attach(co,ex,rear);
		r2=r2->next;
	}
	r1=r1->next;
	while(r1){
    
    //L1第一个结点后面的结点与L2中每一个结点进行乘积。所得结点插入到front初始链表中; 
		r2=L2->next;//重置r2; 
		rear=front;//重置rear,以便于寻找新节点attach的位置; 
		while(r2){
    
    //遍历L2; 
			co=r2->coef*r1->coef;
			ex=r2->expn+r1->expn;//乘积操作; 
			while(rear->next&&ex>rear->next->expn){
    
    //找到链尾或者当前幂指数小于 等于链表中rear->next结点的幂指数 
				rear=rear->next;
			}
			if(rear->next&&ex==rear->next->expn){
    
    //此时已经找到位置;
			//分情况讨论:1.找到一个合适的位置:(1)幂指数相同
				if(co+rear->coef==0){
    
    //找到了一个位置: 
					LinkNode *p=rear->next;
					rear->next=p->next;
					free(p);
				}
				else{
    
    
					rear->next->coef+=co;
				}
			}
			else{
    
    	//2.(1)找到链尾。(2)幂指数不同    
			//即要新建结点; 
				LinkNode *p=(LinkNode*)malloc(sizeof(LinkNode));
				p->coef=co;
				p->expn=ex;
				p->next=rear->next;//两种情况区别在这 
				rear->next=p;
				rear=rear->next;
			}
			r2=r2->next;//遍历 
		} 
		r1=r1->next;//r1的结点乘完;
	}
	return front;
}

然后测试函数就自己写咯!个人认为最好的测试函数是可视化结果的那种。

欢乐的时光总是短暂的,让我们下一次再见!!!

good good studym,day day up! (study hard, improve every day)

猜你喜欢

转载自blog.csdn.net/qq_41606378/article/details/107770320