#include<bits/stdc++.h>
using namespace std;
typedef struct LNode {
float coef;//系数
int expn;//指数
LNode* next;
}LNode,*Linklist;
void Initlist(Linklist& L)//初始化
{
L = new LNode;
L->next = NULL;
}
//冒泡排序单链表
void sortlist(Linklist& L)
{
LNode *wt, *nt, *lastnt = NULL;
for (wt = L->next; wt->next != NULL; wt = wt->next)
{
for (nt = L->next; nt->next != lastnt; nt = nt->next)
{
if (nt->expn > nt->next->expn)//如果当前结点的指数大于下一个将其交换
{
int temp, Temp;//交换两个的指数和系数
temp = nt->coef;
Temp = nt->expn;
nt->expn = nt->next->expn;
nt->coef = nt->next->coef;
nt->next->coef = temp;
nt->next->expn = Temp;
}
}
}
}
//尾插法建立链表
void createlist(Linklist& L)
{
Initlist(L);//初始化链表
LNode* s, * p = L;
printf("请输入多项式一共有多少项:");
int n;
scanf("%d", &n);
if (n <= 0)
{
printf("(输入数字不规范)请重新输入多项式有几项:");
scanf("%d", &n);
}
for(int i=0;i<n;i++)
{
s = new LNode;//生成一个新节点
printf("请输入第%d项的系数和指数分别为:",i+1);
scanf("%f %d",&s->coef,&s->expn);
if (s->coef == 0)//如果输入的系数为0要重新输入
{
printf("请重新输入第%d项的系数和指数分别为:", i + 1);
}
p->next = s;
p = s;
}
p->next = NULL;//由于我上面已经初始化过所以这步可以省略,如果没有初始化的话要让尾指针指向NULL
sortlist(L);//将链表排序将指数小的排在前面一般后续进行加法
}
//加法
Linklist add_list(Linklist &L, Linklist &M)
{
LNode* p = L->next, * q = M->next, * r, * s;
r = L;//让指针r指向L的头节点
while (p && q)//两个工作指针不管谁先遍历到表尾都要跳出while循环
{
if (p->expn < q->expn)//第一种情况如果p的指数小q指针不动让r指向p
{
r->next = p;
p = p->next;
r = r->next;
}
else if (p->expn > q->expn)//同样反过来一样
{
r->next = q;
r = r->next;
q = q->next;
}
else if(p->expn==q->expn)
{
float sum = p->coef + q->coef;
if (sum != 0.0)//如果两者系数相加不为0
{
p->coef = sum;//将系数之和赋给
r->next = p;
r = r->next;
p = p->next;
s = q;
q = q->next;
free(s); // 将M链表上这个无用的结点释放掉节省空间
}
else {
s = p;//如果系数相加等于0的话就要将p和q都释放掉
p = p->next;
free(s);
s = q;
q = q->next;
free(s);
}
}
}
r->next = p ? p : q;//这里用到三元运算符将余下的项加入到链表表尾
return L;
}
//加法(不引用)
Linklist add(Linklist L, Linklist M)
{
Linklist K;
Initlist(K);
LNode* p = L->next, * q = M->next,*r;
r = K;
while (p && q)
{
if (p->expn < q->expn)
{
LNode* t;
t = new LNode;
t = p;
t->next = r->next;
r->next = t;
r = t;
p = p->next;
}
else if (p->expn > q->expn)
{
LNode* c;
c = new LNode;
c = p;
c->next = r->next;
r->next = c;
r = c;
q = q->next;
}
else {
float sum = p -> coef + q->coef;
if (sum != 0.0)
{
LNode* x;
x = new LNode;
x->coef = sum;
x->expn = p->expn;
x->next = r->next;
r->next = x;
r = x;
p = p->next;
q = q->next;
}
else {
p = p->next;
q = q->next;
}
}
}
while (p)
{
r->next = p;
p = p->next;
}
while (q)
{
r->next = q;
q = q->next;
}
r->next = NULL;
return K;
}
//乘法
Linklist Multilist(Linklist& L, Linklist& M)
{
LNode* p, * q, * s, * t;
p = L->next;
q = M->next;
Linklist K;
Initlist(K);
s = K;
int flag = 0;//建立一个flag,这里是为了去特殊处理遍历第一个L的结点时,与M每项相乘所生成的一个多项式
while (p)//外围循环遍历多项式L
{
if (flag == 0)
{
while (q)//内层遍历多项式M
{
LNode* r;
r = new LNode;
float c = p->coef * q->coef;//系数相乘
int d = p->expn + p->expn;//指数相加
r->coef = c;
r->expn=d;
s->next = r;//跟尾插法建立链表一样,将多项式K建立,相当于部分积
r->next = NULL;
s = r;//跟尾插法建立链表一样,将多项式K建立,相当于部分积
q = q->next;//遍历语句
}
}
else {
Linklist LO;
Initlist(LO);
t = LO;
while (q)//跟上面一样
{
LNode* l;
l = new LNode;
l->coef = p->coef * q->coef;
l->expn = p->expn + q->expn;
t->next=l;
l->next = NULL;
t = l;
q = q->next;
}
K = add_list(K, LO);//这一步是让每次的部分积累加,这也是我们flag村走的意义因为第一次每法跟0相加
}
p = p->next;//外围的循环语句
q = M->next;//当然别忘将q指针重置,要不q都不知道循环到哪了
flag = 1;//最后我们让flag等于1表明出来第一次后面都正常
}
return K;
}
//打印我们所进行的一系列操作
void printf_list(Linklist K)
{
LNode* s = K->next;
while (s)
{
if (s->coef != 1.0)//判断是否系数为1,则省略系数
{
if (s->expn != 0)//判断是否指数等于0,则x的0次方为1
printf("%.f*x~%d", s->coef, s->expn);
else
printf("%.f", s->coef);
}
else {
if (s->expn != 0)//判断是否指数等于0
printf("x~%d", s->expn);
else
printf("%.f", s->coef);
}
if (s->next != NULL && s->coef > 0)
printf("+");
s = s->next;
}
printf("\n");
}
int main()
{
Linklist L, M, K, C;
createlist(L);
printf("第一个多项式为:\n");
printf_list(L);
createlist(M);
printf("第二个多项式为:\n");
printf_list(M);
printf("两多项式相加为:\n");
C = add(L, M);
printf_list(C);
K = Multilist(L, M);
printf("两个多项式相乘为:\n");
printf_list(K);
}
一元多项式加法乘法(注释)第二次
于 2024-10-07 17:59:00 首次发布