多项式求和
这里是数据结构个人学习的笔记记录,如有问题欢迎指正说明
解题思路
要计算多项式的和,首先需要用链表创建两个或多个多项式,每个节点有两个数据:系数和指数;其次,如果要实现乱幂输入,那么还需要一个排序函数;然后就是多项式相加求和的部分,当指数相等时其系数相加,如果不相等那么就需要比较大小,依次存入新的链表;最后是输出,而输出需要分情况讨论:系数为正,系数为1不显示系数等。
先来定义结构体变量,和单链表的定义结构体一样,不同的是此时我们的数据变成了两个(系数和指数):
结点的表示方法:
typedef struct LinkNode{
int coefficient;
int exponent;
struct LinkNode *next;
} *LinkList, *NodePtr;
相关操作实现
初始化
/* 初始化 */
LinkList initLinkList(){
LinkList tempHeader = (LinkList)malloc(sizeof(struct LinkNode));
tempHeader->coefficient = 0;
tempHeader->exponent = 0;
tempHeader->next = NULL;
return tempHeader;
}
依次对静态链表中的每个数据元素输出
在这里我做了改动,系数的正负由本身决定,不再有正负号同时存在的情况,还有结尾不会输出符号了
void printList(LinkList paraHeader){
NodePtr p = paraHeader->next;
while (p != NULL) {
printf("%d * 10^%d ", p->coefficient, p->exponent);
if(p->next!=NULL&&p->next->coefficient>0)
{
printf("+ ");
}
p = p->next;
}
printf("\r\n");
}
在链表尾插我们需要计算的数据
这里是尾插
void appendElement(LinkList paraHeader, int paraCoefficient, int paraExponent){
NodePtr p, q;
// Step 1. Construct a new node.
q = (NodePtr)malloc(sizeof(struct LinkNode));
q->coefficient = paraCoefficient;
q->exponent = paraExponent;
q->next = NULL;
// Step 2. Search to the tail.
p = paraHeader;
while (p->next != NULL) {
p = p->next;
}// Of while
// Step 3. Now add/link.
p->next = q;
}
核心求和函数
这是我们这道题的关键之处,就是求和。
最终的输出是第一个链表
void add(NodePtr paraList1, NodePtr paraList2){
NodePtr p, q, r, s;
// Step 1. Search to the position.
p = paraList1->next;
q = paraList2->next;
r = paraList1;
free(paraList2);
while ((p != NULL) && (q != NULL)) {
if (p->exponent < q->exponent) {
//Link the current node of the first list.
printf("case 1\r\n");
r->next = p;
r=p;
printNode(r, 'r');
p = p->next;
printNode(p, 'p');
} else if ((p->exponent > q->exponent)) {
//Link the current node of the second list.
printf("case 2\r\n");
r->next = q;
r = q;
printNode(r, 'r');
q = q->next;
printNode(q, 'q');
} else {
printf("case 3\r\n");
//Change the current node of the first list.
p->coefficient = p->coefficient + q->coefficient;
printf("The coefficient is: %d.\r\n", p->coefficient);
if (p->coefficient == 0) {
printf("case 3.1\r\n");
s = p;
p = p->next;
printNode(p, 'p');
// free(s);
} else {
printf("case 3.2\r\n");
r->next=p;
r = p;
printNode(r, 'r');
p = p->next;
printNode(p, 'p');
}// Of if
s = q;
q = q->next;
//printf("q is pointing to (%d, %d)\r\n", q->coefficient, q->exponent);
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 paixu(NodePtr paraHeader){//将多项式按升幂排序
NodePtr p,q;
int temp,temp1;
for(p=paraHeader->next;p!=NULL;p=p->next){
for(q=p->next;q!=NULL;q=q->next){//q为p的后继结点
if(p->exponent > q->exponent){//如果p的指数比q的指数大,也就是前一项的指数比后一个指数大,那么交换它们的指数和系数
temp = p->exponent;
p->exponent = q->exponent;
q->exponent = temp;
temp1 = p->coefficient;
p->coefficient = q->coefficient;
q->coefficient = temp1;
}
}
}
}
链式存储的代码实现
#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(struct LinkNode));
tempHeader->coefficient = 0;
tempHeader->exponent = 0;
tempHeader->next = NULL;
return tempHeader;
}
void printList(LinkList paraHeader){
NodePtr p = paraHeader->next;
while (p != NULL) {
printf("%d * 10^%d ", p->coefficient, p->exponent);
if(p->next!=NULL&&p->next->coefficient>0)
{
printf("+ ");
}
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;
// Step 1. Construct a new node.
q = (NodePtr)malloc(sizeof(struct LinkNode));
q->coefficient = paraCoefficient;
q->exponent = paraExponent;
q->next = NULL;
// Step 2. Search to the tail.
p = paraHeader;
while (p->next != NULL) {
p = p->next;
}// Of while
// Step 3. Now add/link.
p->next = q;
}// Of appendElement
void add(NodePtr paraList1, NodePtr paraList2){
NodePtr p, q, r, s;
// Step 1. Search to the position.
p = paraList1->next;
q = paraList2->next;
r = paraList1; // Previous pointer for inserting.
free(paraList2); // The second list is destroyed.
while ((p != NULL) && (q != NULL)) {
if (p->exponent < q->exponent) {
//Link the current node of the first list.
r->next = p;
r=p;
p = p->next;
} else if ((p->exponent > q->exponent)) {
//Link the current node of the second list.
r->next = q;
r = q;
q = q->next;
} else {
//Change the current node of the first list.
p->coefficient = p->coefficient + q->coefficient;
if (p->coefficient == 0) {
s = p;
p = p->next;
free(s);
} else {
r->next=p;
r=p;
p = p->next;
}
s = q;
q = q->next;
free(s);
}
}
if (p == NULL) {
r->next = q;
} else {
r->next = p;
}
printf("Addition ends.\r\n");
}
void paixu(NodePtr paraHeader){//将多项式按升幂排序
NodePtr p,q;
int temp,temp1;
for(p=paraHeader->next;p!=NULL;p=p->next){//运用了两个for循环
for(q=p->next;q!=NULL;q=q->next){//q为p的后继结点
if(p->exponent > q->exponent){//如果p的指数比q的指数大,也就是前一项的指数比后一个指数大,那么交换它们的指数和系数
temp = p->exponent;
p->exponent = q->exponent;
q->exponent = temp;
temp1 = p->coefficient;
p->coefficient = q->coefficient;
q->coefficient = temp1;
}
}
}
}
void additionTest(){
LinkList tempList1 = initLinkList();
appendElement(tempList1, 7, 0);
appendElement(tempList1, 3, 1);
appendElement(tempList1, 9, 8);
appendElement(tempList1, 10, 11);
appendElement(tempList1, 5, 17);
printList(tempList1);
LinkList tempList2 = initLinkList();
appendElement(tempList2, 8, 1);
appendElement(tempList2, 22, 7);
appendElement(tempList2, -9, 10);
appendElement(tempList2, -9, 12);
printList(tempList2);
add(tempList1, tempList2);
printList(tempList1);
}
void main(){
additionTest();
printf("Finish.\r\n");
}
样例输出
7 * 10^0 + 3 * 10^1 + 9 * 10^8 + 10 * 10^11 + 5 * 10^17
8 * 10^1 + 22 * 10^7 -9 * 10^10 -9 * 10^12
Addition ends.
7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 9 * 10^8 -9 * 10^10 + 10 * 10^11 -9 * 10^12 + 5 * 10^17
Finish.
写在最后
多项式求和其实还可以完成的更好,比如我们还可以考虑系数为1和指数为0的情况等等。