多项式的加法是链表的基本应用,也有助于理解压缩表示。
代码:#include#include 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); p = p->next; } printf("rn"); } void printNode(NodePtr paraPtr, char paraChar) { if (paraPtr == NULL) { printf("NULLrn"); } else { printf("The element of %c is (%d * 10^%d)rn", paraChar, paraPtr->coefficient, paraPtr->exponent); } } void appendElement(LinkList paraHeader, int paraCoefficient, int paraExponent) { NodePtr p, q; // 1.创建一个新的结点 q = (NodePtr)malloc(sizeof(struct LinkNode)); q->coefficient = paraCoefficient; q->exponent = paraExponent; q->next = NULL; // 2.遍历链表 p = paraHeader; while (p->next != NULL) { p = p->next; } // 3.连接链表 p->next = q; } void add(LinkList paraList1, LinkList paraList2) { NodePtr p, q, r, s; // 1.找到位置 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) { // 应该排链表1里的结点 printf("case 1rn"); r->next = p; r = p; printNode(r, 'r'); p = p->next; printNode(p, 'p'); } else if (p->exponent > q->exponent) { // 应该排链表2里的结点 printf("case 2rn"); r->next = q; r = q; printNode(r, 'r'); q = q->next; printNode(q, 'q'); } else { printf("case 3rn"); //Change the current node of the first list. p->coefficient = p->coefficient + q->coefficient; printf("The coefficient is: %d.rn", p->coefficient); if (p->coefficient == 0) { printf("case 3.1rn"); s = p; p = p->next; printNode(p, 'p'); } else { printf("case 3.2rn"); r->next = p; r = p; // 连接 printNode(r, 'r'); p = p->next; printNode(p, 'p'); } s = q; q = q->next; free(s); // 释放不使用的内存空间 } printf("p = %p, q = %p rn", p, q); } printf("End of while.rn"); if (p == NULL) { r->next = q; } else { r->next = p; } printf("Addition ends.rn"); } void additionTest() { // Step 1. 创建第一个链表 LinkList tempList1 = initLinkList(); appendElement(tempList1, 7, 0); appendElement(tempList1, 3, 1); appendElement(tempList1, 9, 8); appendElement(tempList1, 5, 17); printList(tempList1); // Step 2. 创建第一个链表 LinkList tempList2 = initLinkList(); appendElement(tempList2, 8, 1); appendElement(tempList2, 22, 7); appendElement(tempList2, -9, 10); printList(tempList2); // Step 3. 整合 add(tempList1, tempList2); printList(tempList1); } int main() { additionTest(); printf("Finish.rn"); return 0; }
根据陈涛同学的代码对老师的代码进行了修改
一些想法:老师的代码是相当于用尾插法创建链表的,只能在插入链表的时候就按顺序插入,不然程序就会出错,解决这个问题有两种思路,一是在插入之后排个序,但是链表排序本身比较麻烦,同时在这个问题中如果先后插入了两个次项相同的元素还要在排序中考虑合并的问题,所以就更麻烦了,第二个思路是在插入元素时不采用尾插法,而是在插入时就判断该插入的位置,判断里再加入对同类项的判断,这样代码应该会简洁不少。



