直接上代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
typedef struct Node List;
struct Node
{
int m;
int n;
List * next;
};
List *CreatList(); //创建链表
List *FunSum(List*p, List*q); //求和函数
List *FunMult(List*p, List*q); //求乘积函数
void traverse(List *p); //遍历链表
int main()
{
List *L1, *L2;
List *sum, *mult;
L1 = CreatList();
L2 = CreatList();
mult = FunMult(L1, L2);
traverse(mult);
printf("
");
sum = FunSum(L1, L2);
traverse(sum);
system("pause");
return 0;
}
List * CreatList()
{
int len;
List *p = (List *)malloc(sizeof(List));
List *temp1, *temp2 = p;
scanf("%d", &len); //链表长度
for (int i = 0; i < len; i++)
{
temp1 = (List *)malloc(sizeof(List));
scanf("%d", &temp1->m); //系数m
scanf("%d", &temp1->n); //指数
temp2->next = temp1;
temp2 = temp2->next;
}
temp2->next = NULL;
return p;
}
List * FunSum(List * p, List * q)
{
List *head = (List *)malloc(sizeof(List));
List *temp1 = p->next;
List *temp2 = q->next;
List *temp, *temp3 = head;
List *temp4 = head; //比temp3慢一步的指针
while (NULL != temp1 && NULL != temp2)
{
temp = (List *)malloc(sizeof(List));
temp3->next = temp;
temp3 = temp3->next;
if (temp1->n > temp2->n)
{
temp->m = temp1->m;
temp->n = temp1->n;
temp1 = temp1->next;
}
else if (temp1->n == temp2->n)
{
temp->n = temp2->n;
temp->m = temp2->m + temp1->m;
if (0 == temp->m) //如果系数为0,那么这一项不存在
{
temp3 = temp4; //temp3返回到上一个节点
free(temp); //释放的,否则内存泄漏
}
temp2 = temp2->next;
temp1 = temp1->next;
}
else if (temp1->n < temp2->n)
{
temp->m = temp2->m;
temp->n = temp2->n;
temp2 = temp2->next;
}
temp4 = temp4->next;
}
if (NULL == temp1)
{
while (NULL != temp2)
{
temp = (List *)malloc(sizeof(List));
temp3->next = temp;
temp3 = temp3->next;
temp->m = temp2->m;
temp->n = temp2->n;
temp2 = temp2->next;
}
temp3->next = NULL;
}
else
{
while (NULL != temp1)
{
temp = (List *)malloc(sizeof(List));
temp3->next = temp;
temp3 = temp3->next;
temp->m = temp1->m;
temp->n = temp1->n;
temp1 = temp1->next;
}
temp3->next = NULL;
}
return head;
}
List * FunMult(List * p, List * q)
{
List *head = (List *)malloc(sizeof(List));
List *temp1, *temp2;
temp1 = p->next;
temp2 = q->next;
if (NULL == temp1 || NULL == temp2) //如果其中一个多项式是0,那么乘积是0
{
head->next = NULL;
return head;
}
List *temp3, *temp4;
temp3 = temp4 = head;
List * temp = NULL;
while (NULL != temp1) //用q的第一个元素乘以p的每一个元素,生成的第一轮的表
{
temp = (List *)malloc(sizeof(List));
temp->m = temp1->m * temp2->m;
temp->n = temp1->n + temp2->n;
temp3->next = temp;
temp3 = temp3->next;
temp1 = temp1->next;
}
temp3->next = NULL;
temp2 = q->next->next;
while (NULL != temp2) //在第一轮的表的基础上进行乘积插入
{
temp1 = p->next;
while (NULL != temp1)
{
temp4 = head;
temp3 = head->next;
temp = (List *)malloc(sizeof(List));
temp->m = temp2->m * temp1->m;
temp->n = temp2->n + temp1->n;
while (NULL != temp3)
{
//直到temp->n >= temp3->n时才插入
if (temp->n > temp3->n)
{
temp->next = temp3;
temp4->next = temp;
break;
}
else if(temp->n == temp3->n)
{
temp3->m += temp->m;
if (0 == temp3->m) //如果系数为0,那么删除这一项
{
temp4->next = temp3->next; //将链表接起来
free(temp3); //释放掉
}
free(temp); //释放掉
break;
}
temp4 = temp4->next;
temp3 = temp3->next;
}
if (NULL == temp3)
{
temp4->next = temp;
temp->next = NULL;
}
temp1 = temp1->next;
}
temp2 = temp2->next;
}
return head;
}
void traverse(List * p)
{
List *temp = p->next;
if (NULL == temp)
{
printf("0 0");
return;
}
else
{
printf("%d %d", temp->m, temp->n);
temp = temp->next;
}
while (NULL != temp)
{
printf(" %d %d", temp->m, temp->n);
temp = temp->next;
}
}
上次合并链表的时候,是在原节点上进行的操作,最终导致原链表的丢失。这次的加法和乘法操作,只能是复制原节点,否则破坏掉原节点后,下一个运算就无法进行了。需要注意的一点是:同类型合并的过程中可能会产生系数为0的项,这时候必须删除这一项。删除掉节点后记得释放掉这块空间,否则导致内存泄漏。这个内存泄漏在C/C++中是非常严重的一件事。算法本身很直接,写起来可能麻烦点,但是没有什么值得说的。