1.代码部分
先上代码,后说废话:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>
typedef struct LinkNode {
int coefficient; //系数
int exponent; //指数
struct LinkNode* next;
}* LinkList, * NodePtr;
/*Initialize the list with a header
* @return the pointer to the header
*/
LinkList initLinkList() {
LinkList tempHeader = (LinkList)malloc(sizeof(struct LinkNode));
tempHeader->coefficient = 0;
tempHeader->exponent = 0;
tempHeader->next = NULL;
return tempHeader;
}
/*print the list
* @param paraHeader The header of the list
*/
void printList(LinkList paraHeader) {
NodePtr p = paraHeader->next;
while (p != NULL) {
if (p->next != NULL) {
printf("%d * 10^%d + ", p->coefficient, p->exponent);
p = p->next;
}
else {
printf("%d * 10^%d ", p->coefficient, p->exponent);
p = p->next;
}
}
printf("\n");
}
/*print one node for testing
* @param paraPtr the pointer to the node
* @param paraChar the name of the node
*/
void printNode(NodePtr paraPtr, char paraChar) {
if (paraPtr == NULL) {
printf("NULL\n");
}
else {
printf("the element of %c is (%d+10^%d)\n", paraChar, paraPtr->coefficient, paraPtr->exponent);
}
}
/*
* Add an element to the tail
* @param paraHeader The header of the list
* @param paraCoefficient The coefficient of the new element
* @param paraExponent The exponent of the new element
*/
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;
}
// if (p->next->exponent > q->exponent) {
// do{
// p = p->next;
// } while (p->next->exponent < q->exponent);
// q->next = p->next;
// q->next = q;
// }
// else if (p->next->exponent == q->exponent) {
// p->coefficient += q->coefficient;
// }
// else {
// q->next = p->next;
// p->next = q;
// }
//}
/*
* Polynomial addition(多项式加法)
* @param paraList1 The first list
* @param paraList2 The second list
*/
void add(NodePtr paraList1, NodePtr paraList2) {
NodePtr p, q, r, s;
//Step 1: Search to the position
p = paraList1->next;
printNode(p, 'p');
q = paraList2->next;
printNode(q, 'q');
r = paraList1; //此时paraList的头节点为r
printNode(r, 'r');
free(paraList2); //销毁头节点,现在paraList2无头节点,首元素地址为q;
while ((p != NULL) && (q != NULL)) {
if (p->exponent < q->exponent) {
printf("case 1\n");
r->next = p;//为什么
r = p;
printNode(r, 'r');
p = p->next;
printNode(p, 'p');
}
else if (p->exponent > q->exponent) {
printf("case 2\n");
r->next = q;
r = q;
printNode(r, 'r');
q = q->next;
printNode(q, 'q');
}
else {
printf("case 3\n");
p->coefficient += q->coefficient;
printf("The coefficient is %d\n", p->coefficient);
if (p->coefficient == 0) {
printf("case 3.1\n");
s = p;//有什么意义?
p = p->next;
printNode(p, 'p');
}
else {
printf("case 3.2\n");
r = p;
printNode(r, 'r');
p = p->next;
printNode(p, 'p');
}
s = q;
q = q->next;
free(s);
}
printf("p=%ld,q=%ld\n", p, q);
}
printf("End fo while.\n");
if (p == NULL) {
r->next = q;
}
else {
r->next = p;
}
printf("Addition ends.\n");
}
/**
* Unit test 1.
*/
void additionTest1() {
// 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);
printf("The result is: ");
printList(tempList1);
printf("\r\n");
}// Of additionTest1
/**
* Unit test 2.
*/
void additionTest2() {
// 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, 10);
printList(tempList2);
// Step 3. Add them to the first.
add(tempList1, tempList2);
printf("The result is: ");
printList(tempList1);
printf("\r\n");
}// Of additionTest2
/**
* The entrance.
*/
int main() {
additionTest1();
additionTest2();
printf("Finish.\r\n");
return 0;
}// Of main
2.运行结果
7 * 10^0 + 3 * 10^1 + 9 * 10^8 + 5 * 10^17
8 * 10^1 + 22 * 10^7 + -9 * 10^8
the element of p is (7+10^0)
the element of q is (8+10^1)
the element of r is (0+10^0)
case 1
the element of r is (7+10^0)
the element of p is (3+10^1)
p=-879103840,q=-879102880
case 3
The coefficient is 11
case 3.2
the element of r is (11+10^1)
the element of p is (9+10^8)
p=-879102400,q=-879103440
case 2
the element of r is (22+10^7)
the element of q is (-9+10^8)
p=-879102400,q=-879102560
case 3
The coefficient is 0
case 3.1
the element of p is (5+10^17)
p=-879102800,q=0
End fo while.
Addition ends.
The result is: 7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 5 * 10^17
7 * 10^0 + 3 * 10^1 + 9 * 10^8 + 5 * 10^17
8 * 10^1 + 22 * 10^7 + -9 * 10^10
the element of p is (7+10^0)
the element of q is (8+10^1)
the element of r is (0+10^0)
case 1
the element of r is (7+10^0)
the element of p is (3+10^1)
p=-879103520,q=-879103600
case 3
The coefficient is 11
case 3.2
the element of r is (11+10^1)
the element of p is (9+10^8)
p=-879103920,q=-879103280
case 2
the element of r is (22+10^7)
the element of q is (-9+10^10)
p=-879103920,q=-879103200
case 1
the element of r is (9+10^8)
the element of p is (5+10^17)
p=-879103760,q=-879103200
case 2
the element of r is (-9+10^10)
NULL
p=-879103760,q=0
End fo while.
Addition ends.
The result is: 7 * 10^0 + 11 * 10^1 + 22 * 10^7 + 9 * 10^8 + -9 * 10^10 + 5 * 10^17
Finish.
D:\visual studio\多项式加法\x64\Debug\多项式加法.exe (进程 14212)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
3.大体思路
我认为实现多项式加法的核心就是add函数,这里整理了一下实现add函数的思路
设两个待相加的多项式的链表的头指针分别为head1(第一个多项式)和head2(第二个多项式),两者的和保存到链表head1中。只需要先将head1和head2链表的首结点作为当前结点(分别用p和q指向)开始检测,在遍历链表的过程中,分情况作如下处理:
(1)若两个多项式中当前结点的指数值相同,则它们的系数相加,结果保存到p结点,并将q结点删除。如果相加后的系数不为0,p指向第一个多项式的下一个结点,若为0,则将当前p结点删除。
(2)当两个多项式中对应结点的指数值不相等时,若p指向的结点的指数小,则p直接指向下一结点即可;而q指向的结点小时,需要将q结点插入到p前,然后q再重新指回到第二个多项式中的下一结点,继续进行处理。这里涉及多个指针间的操作,容易弄混。
(3)检测过程直到其中的任一个链表结束。若p不为空,第一个多项式中的剩余项已经在链表中,不作处理,如果q不为空,说明此时第二个多项式中剩余的节点的指数都大于p中的指数,所以只需要将q链接到相加后的第一个多项式末尾。
初学还是略有生疏,难免有错误和疏漏,欢迎批评指正!