老师版
#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之后会再来更新这篇博客的。