02-线性结构2 一元多项式的乘法与加法运算
这道题是课上例题,不过课上没有给出完整代码,在自己实现时还是遇到了一些细节问题。
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 typedef struct PolyNode *Poly; 5 struct PolyNode 6 { 7 int coef; 8 int expon; 9 Poly Next; 10 }; 11 12 void Attach(int c, int e, Poly *pRear) 13 { 14 Poly tmp; 15 tmp = (Poly)malloc(sizeof(struct PolyNode)); 16 tmp->coef = c; 17 tmp->expon = e; 18 tmp->Next = NULL; 19 (*pRear)->Next = tmp; 20 (*pRear) = tmp; 21 } 22 23 Poly PolyRead() 24 { 25 Poly P, Rear, tmp; 26 P = (Poly)malloc(sizeof(struct PolyNode)); 27 P->Next = NULL; //创建头节点完成 28 Rear = P; 29 int N, c, e, i; 30 scanf("%d", &N); 31 for (i = 0; i < N; i++){ 32 scanf("%d %d", &c, &e); 33 Attach(c, e, &Rear); 34 } 35 tmp = P; 36 P = P->Next; 37 free(tmp); 38 return P; 39 } 40 41 void PolyPrint(Poly P) 42 { 43 int flag = 0; 44 if(!P){ 45 printf("0 0"); 46 } 47 while(P){ 48 if (!flag) 49 flag = 1; 50 else 51 printf(" "); 52 printf("%d %d", P->coef, P->expon); 53 P = P->Next; 54 } 55 printf("\n"); 56 } 57 58 Poly PolyMult(Poly P1, Poly P2) 59 { 60 Poly p1, p2, Rear, tmp, P; 61 int c, e; 62 P = (Poly)malloc(sizeof(struct PolyNode)); 63 P->Next = NULL; 64 Rear = P; 65 p1 = P1; 66 p2 = P2; 67 if(!p1 || !p2) 68 return NULL; 69 while(p2){ 70 c = p1->coef * p2->coef; 71 e = p1->expon + p2->expon; 72 if(c != 0){ 73 Attach(c, e, &Rear); 74 p2 = p2->Next; 75 } 76 } 77 p1 = p1->Next; 78 while(p1){ 79 p2 = P2; 80 Rear = P; 81 while(p2){ 82 c = p1->coef * p2->coef; 83 e = p1->expon + p2->expon; 84 if(c != 0){ 85 86 } 87 while( Rear->Next && Rear->Next->expon > e ){ 88 Rear = Rear->Next; 89 } 90 if ( Rear->Next && Rear->Next->expon == e ){ 91 if ( Rear->Next->coef + c ) 92 Rear->Next->coef += c; 93 else{ 94 tmp = Rear->Next; 95 Rear->Next = tmp->Next; 96 free(tmp); 97 } 98 }else{ 99 tmp = (Poly)malloc(sizeof(struct PolyNode)); 100 tmp->expon = e; 101 tmp->coef = c; 102 tmp->Next = Rear->Next; 103 Rear->Next = tmp; 104 Rear = tmp; 105 } 106 p2 = p2->Next; 107 } 108 p1 = p1->Next; 109 } 110 tmp = P; 111 P = P->Next; 112 free(tmp); 113 return P; 114 } 115 116 Poly PolyAdd(Poly P1, Poly P2) 117 { 118 Poly p1, p2, Rear, tmp, P; 119 int coefSum; 120 P = (Poly)malloc(sizeof(struct PolyNode)); 121 P->Next = NULL; 122 tmp = P; 123 Rear = tmp; 124 p1 = P1; 125 p2 = P2; 126 while(p1 && p2){ 127 if(p1->expon == p2->expon){ 128 coefSum = p1->coef + p2->coef; 129 if(coefSum){ 130 Attach(p1->coef + p2->coef, p1->expon, &Rear); 131 } 132 p1 = p1->Next; 133 p2 = p2->Next; 134 }else if(p1->expon > p2->expon){ 135 Attach(p1->coef, p1->expon, &Rear); 136 p1 = p1->Next; 137 }else if(p1->expon < p2->expon){ 138 Attach(p2->coef, p2->expon, &Rear); 139 p2 = p2->Next; 140 } 141 } 142 if(p1){ 143 Rear->Next = p1; 144 }else if(p2){ 145 Rear->Next = p2; 146 } 147 tmp = P; 148 P = P->Next; 149 free(tmp); 150 return P; 151 } 152 153 int main(int argc, char const *argv[]) 154 { 155 Poly P1, P2, PMul, PAdd; 156 P1 = PolyRead(); 157 P2 = PolyRead(); 158 PMul = PolyMult(P1, P2); 159 PAdd = PolyAdd(P1, P2); 160 PolyPrint(PMul); 161 PolyPrint(PAdd); 162 return 0; 163 }
实现过程中的体会有:
第98行需注意这里有可能出现和NULL比较的情况,所以应该用else条件,具体说来比如新接入的e一直小于当前链表中每一个expon,Rear一直指向最后一个了,再看Rear->Next->expon显然不可。
//之前犯下的错误有:
// if( Rear->Next->expon < e ),运行时直接溢出
// if( Rear->Next && Rear->Next->expon < e ),得出结果不全
另外之后链接结果时不能直接用上面构造的Attach函数; 原因是Attach仅用于接在一个链表的最后(其定义中tmp->Next = NULL)而这里是在一个链表的中间位置插入,故应重新构造并接入一个结点。