MOOC中的视频解释
请读者注意,视频中的实现方法是没有用头结点的链表来表示,但我实现的是带头结点的链表,在这个过程中,带头结点某些地方的代码与视频不同,带头结点的时可能会在PTA提交的时候测试点3出现段错误。。。
乘法大致思路:
乘法中会出现相乘时出现阶相同的情况,需要把这两个的系数相加,若相加为0,则把这个结点删除。
具体操作:
- 假设计算两个多项式相乘P1*P2,先用P1中的第一项乘以P2中每一项来构建一个初始链表(这个初始链表的阶一定是有序的)
- 用P1中剩下的元素乘以P2中每一项,对于P1中的一个元素与P2相乘,这个乘下的阶一定是有有序的,所以对于一个P1中一个元素与P2相乘,我们可以按顺序在初始列表中检索相乘的结果,若阶相同就进行系数相加,和为0就删除结点,若阶小于就插入。
//一元多项式的乘法与加法运算 (带头结点)
typedef struct Polynomial {
int c, e;
struct Polynomial* Next;
}*Ptr;
//不断往链表后面加元素
void Attach(int c, int e, Ptr* PRear) {//PRear是指向Rear的指针
Ptr P = (Ptr)malloc(sizeof(struct Polynomial));
P->c = c; P->e = e; P->Next = NULL;
(*PRear)->Next = P;
*PRear = P;//改变实参Rear的值
}
Ptr ReadPoly() {
Ptr P = (Ptr)malloc(sizeof(struct Polynomial));//P指向头结点,Rear指向最后一个结点
P->Next = NULL;
Ptr Rear = P;
int n, c, e;
scanf_s("%d", &n);
while(n--) {
scanf_s("%d", &c);
scanf_s("%d", &e);
Attach(c, e, &Rear);//Rear指向最后一个结点 当加入元素时Rear的值要改变
//所以不能用值传递,得用指针传递来达到改变Rear的目的
}
return P;
}
Ptr Mult(Ptr P1, Ptr P2) {//相乘 系数× 指数+
Ptr P = (Ptr)malloc(sizeof(struct Polynomial));
P->Next = NULL;
Ptr Rear = P;
P1 = P1->Next; Ptr t = P2->Next;
if (!P1 || !t) return P; 当输入的多项式的个数为0的时候ReadPoly函数返回的为带头结点的空多项式链表 将其直接返回到输出函数时 输出为0 0
while (t) {
Attach(P1->c * t->c, P1->e + t->e, &Rear);
t = t->Next;
}//先初建一个链表 用P1第一项×P2每一项
P1 = P1->Next;
//再将P1中的项×P2中的项的结果插到合适的的位置
while (P1) {
t = P2->Next; Rear = P;//为了检索位置,重新让Rear指向头结点
while (t) { //Rear=P 不在第二层while是因为t中的指数是单调递减的,当插入P1某项与P2某项×时,P2下一项与该P1的×必在该位置的后面 这样可以少运行几次
while (Rear->Next && Rear->Next->e > (P1->e + t->e)) {//指向要插入的位置的前面一项
Rear = Rear->Next;
}
if (Rear->Next && Rear->Next->e == (P1->e + t->e)) {
if (Rear->Next->c + (P1->c * t->c)) {//相同指数相加,系数不为0
Rear->Next->c += (P1->c * t->c);
}
else {
Ptr t = Rear->Next;
Rear->Next = t->Next;
free(t);
}
}
else {
Ptr k = (Ptr)malloc(sizeof(struct Polynomial));
k->c = P1->c * t->c; k->e = P1->e + t->e;
k->Next = Rear->Next;
Rear->Next = k;
Rear = Rear->Next;
}
t = t->Next;
}
P1 = P1->Next;
}
return P;
}
void PrintPoly(Ptr P) {
P = P->Next;
if (!P) { printf("0 0\n"); return; }
int num = 0;
while (P) {
if (num != 0)
printf(" ");
printf("%d %d", P->c, P->e);
num++;
P = P->Next;
}
printf("\n");
}
Ptr Add(Ptr P1, Ptr P2) {
Ptr P = (Ptr)malloc(sizeof(struct Polynomial));
P->Next = NULL;
Ptr Rear = P;
P1 = P1->Next; P2 = P2->Next;
while (P1 && P2) {
if (P1->e > P2->e) {
Attach(P1->c, P1->e, &Rear);
P1 = P1->Next;
}
else if(P1->e == P2->e){
if (P1->c + P2->c) {//系数相加不为0
Attach(P1->c + P2->c, P1->e, &Rear);
}
P1 = P1->Next; P2 = P2->Next;
}
else if (P1->e < P2->e) {
Attach(P2->c, P2->e,&Rear);
P2 = P2->Next;
}
}
if (P1 == NULL) Rear->Next = P2;
else Rear->Next = P1;
return P;
}
int main() {
Ptr P1, P2, PP, PS;
P1 = ReadPoly();
P2 = ReadPoly();
PP = Mult(P1, P2);
PrintPoly(PP);
PS = Add(P1, P2);
PrintPoly(PS);
return 0;
}