数据结构应用--多项式相加

老师版

#include <stdio.h>
#include <malloc.h>

typedef struct LinkNode{
	int coefficient;
	int exponent;
	struct LinkNode *next;
}*LinkList,*NodePtr;

//创建
LinkList initLinkList()
{
	LinkList tempHeader=(LinkList)malloc(sizeof(LinkNode));
	tempHeader->coefficient =0;
	tempHeader->exponent =0;
	tempHeader->next =NULL;
	return tempHeader; 
}

//输出 
void printList(LinkList paraHeader)
{
	NodePtr p=paraHeader;
	while(p!=NULL)
	{
		printf("%d *10^%d +",p->coefficient ,p->exponent );
		p=p->next ;
	}
	printf("\r\n");
} 

//测试程序
void printNode(NodePtr paraPtr,char paraChar)
{
	if(paraPtr==NULL){
		printf("NULL\r\n");
	}else{
		printf("The element of %c is (%d * 10^%d)\r\n", paraChar, paraPtr->coefficient, paraPtr->exponent);
	}
} 

//添加多项式
void appendElement(LinkList paraHeader,int paraCoefficient,int paraExponent)
{
	NodePtr p,q;
	
	q=(NodePtr)malloc(sizeof(struct LinkNode));
	q->coefficient =paraCoefficient;
	q->exponent =paraExponent;
	q->next =NULL;
	
	p=paraHeader;
	while(p->next !=NULL)
	{
		p=p->next ;
	}
	
	p->next =q;
} 

//多项式相加
void add(NodePtr paraList1,NodePtr paraList2)
{
	NodePtr p,q,r,s;
	
	p=paraList1->next ;
	printNode(p,'p');
	q=paraList2->next ;
	printNode(q,'q');
	r=paraList1;
	printNode(r,'r');
	free(paraList2);
	
	while(p!=NULL&&q!=NULL)
	{
		if((p->exponent )<(q->exponent) ){
			printf("case 1\r\n");
			r=p;
			printNode(r,'r');
			p=p->next ;
			printNode(p,'p');
		}else if((p->exponent )>(q->exponent) ){
			printf("\r\n");
			r->next =q;
			r=q;
			printNode(r,'r');
			q=q->next ;
			printNode(q,'q');
		}else{
			printf("case 3\r\n");
			
			p->coefficient =p->coefficient +q->coefficient ;
			printf("The coefficient is: %d.\r\n", p->coefficient);
			if(p->coefficient ==0)
			{
				printf("case3.1\r\n");
				s=p;
				p=p->next ;
				printNode(p,'p');
				free(s);
			}else{
				printf("case3.2\r\n");
				r=p;
				printNode(r,'r');
				p=p->next ;
				printNode(p,'p');
			}
			s=q;
			q=q->next ;
			free(s);
		}
		printf("p=%ld,q=%ld\r\n",p,q);
	}
	printf("End of while.\r\n");
	
	if(p==NULL){
		r->next =q;
	}
	else{
		r->next =p;
	}
	
	printf("Addition ends.\r\n");
} 

//测试代码 
void additionTest(){
	// Step 1. Initialize the first polynomial.
	LinkList tempList1 = initLinkList();
	appendElement(tempList1, 7, 0);
	appendElement(tempList1, 3, 1);
	appendElement(tempList1, 9, 8);
	appendElement(tempList1, 5, 17);
	printList(tempList1);

	// Step 2. Initialize the second polynomial.
	LinkList tempList2 = initLinkList();
	appendElement(tempList2, 8, 1);
	appendElement(tempList2, 22, 7);
	appendElement(tempList2, -9, 8);
	printList(tempList2);

	// Step 3. Add them to the first.
	add(tempList1, tempList2);
	printList(tempList1);
}

int main(){
	additionTest();
	printf("Finish.\r\n");
}

心得体会

前面几篇博客都在详细去分析整个代码的运作过程,更偏向于理论性的东西,所以这一篇会少些文字和图解。
整体代码写下来其实感觉不难,我觉得重点在逻辑要清楚,然后思路最好是清晰不断的。下面我展示一下自己敲的版本。

自己敲版

由于其他的部分都大同小异,所以我只展示最重要的add函数

void add(PNODE paraList1,PNODE paraList2)
{
	PNODE p,q,r,s;
	
	p=paraList1->pNext ;
	q=paraList2->pNext ;
	r=paraList1;
	free(paraList2);

	while(p!=NULL&&q!=NULL)
	{
		if((p->Clo )>(q->Clo ) )
		{
			printf("p的指数大于q\r\n");
			printf("p = ");
			print(p);
			r->pNext =q;
			r=q;//把r指向我们挪动前的那一个元素,使链表链接 ;
			q=q->pNext ;
		}else if((p->Clo )<(q->Clo ))
		{
			printf("p的指数小于q\r\n");
			printf("p = ");
			print(p);
			r->pNext =p;
			r=p;
			p=p->pNext ;
			
		}else
		{
			p->Coe =p->Coe +q->Coe ;
			if(p->Coe ==0)//唯一一个不需要链接节点的情况 
			{
				printf("二者指数相等,系数相加为0\r\n");
				s=p;
				p=p->pNext ;
				free(s);
			}else
			{
				printf("二者指数相等,系数相加不为0\r\n");
				printf("p = ");
			    print(p);
				r->pNext =p;
				r=p;//在二者系数相加不等于0时,也要将p链接到r上; 
				p=p->pNext ;
			}
			s=q;
			q=q->pNext ;
			free(s);//q节点两种情况下都会被释放 
		}
		printf("\r\nwhile end\r\n");
	}
	
	if(p==NULL)
	{
		r->pNext =q;
	}else
	{
		r->pNext =p;
	}
	
	printf("HOLE END\r\n");
}

详细的说明我都已经附在代码中。首先是陈涛同学发现的老师在p,q系数相加却不为0时忘记了将p链接到r上的问题,其次是我把老师运行结果尾部的那个加号去除了,因为看着实在有些不舒服。。
另外,我发现整个代码能够解决的多项式相加其实比较局限,先上运行结果:

运行结果

1 * 1^2 + 3 * 2^1 + 9 * 2^8 + 5 * 2^17
2 * 2^1 + 22 * 2^7 + -9 * 2^8
p的指数大于q
p = 1 * 1^2
while end
p的指数小于q
p = 1 * 1^2
while end
p的指数小于q
p = 3 * 2^1
while end
p的指数大于q
p = 9 * 2^8
while end
二者指数相等,系数相加为0

while end
HOLE END
2 * 2^1 + 1 * 1^2 + 3 * 2^1 + 22 * 2^7 + 5 * 2^17

两版代码的局限性

通过这个运行结果,我发现在这个测试用例中,最终结果的第一项和第三项本应该合并,但是却没有出现我期待的结果,我一开始以为是自己的代码敲错了,后来我又用类似的测试用例分别测试了我的和老师的代码,发现都存在这个问题:即这个代码只能解决当p的第一项系数小于q的第一项时的多项式相加,如果后来再出现可以合并的项时,因为我们在链接时已经把前面那个项链接到r上了,所以无法再对后面的项进行合并。
我的初步解决想法是把r拿来遍历寻找可以再合并的项,这只是一个粗略的不能再粗略的构想,等我做完pta之后会再来更新这篇博客的。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值