1.理论
一元多项式可以很容易的表示为线性表如:2*X^8-9*X^5+5*X^2+8,构成的线性表为{{2,8}, {-9,5}, {5,2}, {8,0}},线性表的每个数据元素为{系数,上标}的形式。考虑到多项式的次数可能很高且变化很大,我们采用双向链表的形式来作为多项式的逻辑结构。
我们假设输入的多项式按照次数的高低从前往后排列,不满足这一条件的使用排序来达到这样的效果。这样进行多项式的加、减操作时,只需要分配一个新的链表,从前往后遍历两个相加、减的多项式,比较多项式项次数的高低来插入较高次数的多项式到新链表,次数相等的多项式项加、减对应的基数后再插入。多项式的乘法就是展开各个项相乘后再累加起来,原理是一样的。
下面是部分实现程序,其中注意完整程序加减法都提供了一个Slow版本和一个Fast版本:Slow版本就是新分配一个链表,遍历多项式的两个链表项复制它们的值来插入,需要动态开辟内存,相对较慢;Fast版本利用了指针的特性,直接将各个项串接起来,相对较快,但是这样导致原来相加、减的两个多项式项的链表发生了变化,这是我们不希望看到的,如果非要这个函数,必须先复制两个多项式做备份,这里放上这个Fast函数只是为了补充说明链表合并的方便性。
2.实现程序
链表存储结构
typedef struct { int base; //多项式系数,头节点用它保存长度 int superscript; //多项式次数(上标) } JWListElem; typedef struct tagJWListNode { JWListElem elem; //数据元素 struct tagJWListNode *pNext; //下一个节点指针 struct tagJWListNode *pPrior; //上一个节点指针 }JWListNode, *PJWListNode, JWList, *PJWList;
typedef PJWList Poly ;
多项式操作函数
/* 功能:将两个从高次到低次排序好的多项式相加 输入:多项式p1和p2 输出:相加后的多项式 说明:由于结果的生成要不断的重新申请空间运行速度相对较慢,但是p1和p2保持不变 */ Poly PolyAddSlow(Poly p1, Poly p2) { Poly pAdd,pTemp1,pTemp2; JWListElem AddTemp; //相加过程中的临时变量 pAdd = JWListCreateFromHead(0, NULL); //相加的结果pAdd pTemp1 = p1->pNext; //多项式p1的移动指针pTemp1 pTemp2 = p2->pNext; //多项式p2的移动指针pTemp2 //两者交替比较,上标大的先插入,相同上标时基数累加 while(pTemp1 != NULL && pTemp2 != NULL) { if(pTemp1->elem.superscript > pTemp2->elem.superscript) { JWListInsert(pAdd, JWListGetLength(pAdd), pTemp1->elem); pTemp1 = pTemp1->pNext; } else if(pTemp1->elem.superscript < pTemp2->elem.superscript) { JWListInsert(pAdd, JWListGetLength(pAdd), pTemp2->elem); pTemp2 = pTemp2->pNext; } else { AddTemp.base = pTemp1->elem.base + pTemp2->elem.base; if(0 != AddTemp.base)//剔除相加后基数变为0的情况 { AddTemp.superscript = pTemp1->elem.superscript; JWListInsert(pAdd, JWListGetLength(pAdd), AddTemp); } pTemp1 = pTemp1->pNext; pTemp2 = pTemp2->pNext; } } //将剩余的全部插在链表结尾 while(pTemp1 != NULL) { JWListInsert(pAdd, JWListGetLength(pAdd), pTemp1->elem); pTemp1 = pTemp1->pNext; } while(pTemp2 != NULL) { JWListInsert(pAdd, JWListGetLength(pAdd), pTemp2->elem); pTemp2 = pTemp2->pNext; } return pAdd; } /* 功能:将两个从高次到低次排序好的多项式相减 输入:多项式p1和p2,p1-p2 输出:相减后的多项式 说明:由于结果的生成要不断的重新申请空间运行速度相对较慢,但是p1和p2保持不变 */ Poly PolySubtractSlow(Poly p1, Poly p2) { Poly pSub,pTemp1,pTemp2; JWListElem SubTemp; //相减过程中的临时变量 pSub = JWListCreateFromHead(0, NULL); //相减的结果pSub pTemp1 = p1->pNext; //多项式p1的移动指针pTemp1 pTemp2 = p2->pNext; //多项式p2的移动指针pTemp2 //两者交替比较,上标大的先插入,相同上标时基数相减 while(pTemp1 != NULL && pTemp2 != NULL) { if(pTemp1->elem.superscript > pTemp2->elem.superscript) { JWListInsert(pSub, JWListGetLength(pSub), pTemp1->elem); pTemp1 = pTemp1->pNext; } else if(pTemp1->elem.superscript < pTemp2->elem.superscript) { SubTemp.base = 0 - pTemp2->elem.base; SubTemp.superscript = pTemp2->elem.superscript; JWListInsert(pSub, JWListGetLength(pSub), SubTemp); pTemp2 = pTemp2->pNext; } else { SubTemp.base = pTemp1->elem.base - pTemp2->elem.base; if(0 != SubTemp.base)//剔除相减后基数变为0的情况 { SubTemp.superscript = pTemp1->elem.superscript; JWListInsert(pSub, JWListGetLength(pSub), SubTemp); } pTemp1 = pTemp1->pNext; pTemp2 = pTemp2->pNext; } } //将剩余的全部插在链表结尾 while(pTemp1 != NULL) { JWListInsert(pSub, JWListGetLength(pSub), pTemp1->elem); pTemp1 = pTemp1->pNext; } while(pTemp2 != NULL) { SubTemp.base = 0 - pTemp2->elem.base; SubTemp.superscript = pTemp2->elem.superscript; JWListInsert(pSub, JWListGetLength(pSub), SubTemp); pTemp2 = pTemp2->pNext; } return pSub; } /* 功能:将两个从高次到低次排序好的多项式相乘 输入:两个多项式p1和p2 输出:相乘后的多项式 */ Poly PolyMultiply(Poly p1, Poly p2) { Poly pMulti, pMultiTemp, pTemp1, pTemp2, pLine; JWListElem eTemp; pMultiTemp = pMulti = JWListCreateFromHead(0, NULL); pTemp1 = p1->pNext; //循环展开多项式 while(pTemp1 != NULL) { pLine = JWListCreateFromHead(0, NULL); //创建新的一次展开计算 pTemp2 = p2->pNext; //重置pTemp2循环初始值 while(pTemp2 != NULL) { eTemp.base = pTemp1->elem.base * pTemp2->elem.base; eTemp.superscript = pTemp1->elem.superscript * pTemp2->elem.superscript; JWListInsert(pLine, JWListGetLength(pLine), eTemp);//展开项构成新的多项式 pTemp2 = pTemp2->pNext; } //将已有结果累加 PolySort(pLine);//调整pTemp1的负上标和pTemp2相乘后上标排列顺序还是从高到低!!! pMulti = PolyAddSlow(pMultiTemp, pLine); //删除上一次展开计算的结果 JWListDestroy(pMultiTemp); JWListDestroy(pLine); pMultiTemp = pMulti; pTemp1 = pTemp1->pNext; } return pMulti; }
3.运行结果
这里放上示例计算结果供对比
完整程序下载链接
原创,转载请注明来自http://blog.csdn.net/wenzhou1219