多项式运算我用的方法是直接在L1上进行改动。
我出现的问题是当链表L1,L2中的元素指数相等且系数相加等于0时,计算之后还是L1中的系数,没有发生变化。还有一个问题是当L2中的元素的指数都与L1元素指数不相等时,我在L1后面添加尾元素来存储该元素,但是没有添加成功。
下面是我的核心代码:
Sqlist Operation(Sqlist *&L1,Sqlist *L2)
{
Sqlist *p1,*p2,*s;
p2=L2->next;
while(p2!=NULL)
{
p1=L1->next; //每次循环都指向首元结点
while(p1!=NULL)
{
if(p1->data.j==p2->data.j) //两个元素指数相等
{
p1->data.i += p2->data.i; //系数相加
continue; //结束内层循环
}
p1=p1->next;
}
if(p1==NULL) //特殊情况:L2中的元素指数L1中没有,插入新结点
{
s=(Sqlist *)malloc(sizeof(Sqlist)); //产生新结点,这里的s是尾结点
s=p2; //新结点赋值
s->next=NULL;
p1=s;
}
p2=p2->next;
}
return *L1;
}
还有一点是当两个指数相等的元素系数相加等于0时,我没有直接在链表的基础上删除该元素,而是在输出链表的时候跳过该系数为0的元素。
下面是我的输出代码:
void Displist(Sqlist *L)
{
Sqlist *p=L->next;
printf("%dx^(%d)",p->data.i,p->data.j);
p=p->next;
while(p)
{
if(p->data.i==0)
p=p->next;
if(p->data.i>0)
printf("+%dx^(%d)",p->data.i,p->data.j);
else
printf("%dx^(%d)",p->data.i,p->data.j);
p=p->next;
}
}
下面是我的完整代码:
#include <stdio.h>
#include <malloc.h>
typedef struct infor
{
int i; //指数
int j; //系数
}ss;
typedef struct node
{
ss data;
struct node *next;
}Sqlist;
void Initlist(Sqlist *&L)
{
L=(Sqlist *)malloc(sizeof(Sqlist));
L->next=NULL;
}
void Createlist(Sqlist *&L,ss a[],int n) //尾插法建立链表
{
Sqlist *r=L; //尾指针指向头结点
Sqlist *s;
for(int i=0;i<n;i++)
{
s=(Sqlist *)malloc(sizeof(Sqlist));
s->data=a[i];
s->next=NULL;
r->next=s;
r=s;
}
r->next=NULL; //尾指针指针域置空
}
bool Deletelist(Sqlist *&L,int n)
{
ss s; //用来暂时存放删除结点的信息
Sqlist *p=L,*q; //指向首结点
int i=0;
while(i<n-1 && p) //寻找要删除结点的前一个结点
{
p=p->next; //p在这里指的就是要删除的结点的前一个节点
i++;
}
if(p==NULL) return false;
else
{
q=p->next;
if(q==NULL) return false; //一共有7个元素,寻找第8个元素,第7个元素能召见,第8个找不见
s=q->data;
p->next=q->next;
free(q);
return true;
}
}
Sqlist Operation(Sqlist *&L1,Sqlist *L2)
{
Sqlist *p1,*p2,*s;
p2=L2->next;
while(p2!=NULL)
{
p1=L1->next; //每次循环都指向首元结点
while(p1!=NULL)
{
if(p1->data.j==p2->data.j) //两个元素指数相等
{
p1->data.i += p2->data.i; //系数相加
continue; //结束内层循环
}
p1=p1->next;
}
if(p1==NULL) //特殊情况:L2中的元素指数L1中没有,插入新结点
{
s=(Sqlist *)malloc(sizeof(Sqlist)); //产生新结点,这里的s是尾结点
s=p2; //新结点赋值
s->next=NULL;
p1=s;
}
p2=p2->next;
}
return *L1;
}
void Displist(Sqlist *L)
{
Sqlist *p=L->next;
printf("%dx^(%d)",p->data.i,p->data.j);
p=p->next;
while(p)
{
if(p->data.i==0)
p=p->next;
if(p->data.i>0)
printf("+%dx^(%d)",p->data.i,p->data.j);
else
printf("%dx^(%d)",p->data.i,p->data.j);
p=p->next;
}
}
int main()
{
ss a[4]={{7,0},
{3,1},
{9,8},
{5,17}};
ss b[3]={{8,1},
{22,7},
{-9,8}};
Sqlist *L1,*L2,*L3;
int m,n,t;
Initlist(L1);
Initlist(L2);
Initlist(L3);
m=sizeof(a)/sizeof(ss);
n=sizeof(b)/sizeof(ss);
Createlist(L1,a,m);
Createlist(L2,b,n);
Displist(L1);
printf("+");
Displist(L2);
printf("=");
*L3=Operation(L1,L2);
Displist(L3);
}
下面是我的运行结果(很显然是错误的):
【以下回答由 GPT 生成】
优化多项式运算算法可以考虑以下几点改进建议:
问题1:当指数相等且系数相加等于0时,L1中的系数没有发生变化。 解决方案:在判断系数相加等于0时,应删除该节点,而不是继续遍历链表。 c if (p1->data.j == p2->data.j) // 两个元素指数相等 { p1->data.i += p2->data.i; // 系数相加 if (p1->data.i == 0) // 系数等于0,删除该节点 { // 删除p1节点 Sqlist *temp = p1; p1 = p1->next; L1->next = p1; free(temp); } continue; // 结束内层循环 }
问题2:L2中的元素的指数与L1中的元素指数不相等时,插入新节点没有成功。 解决方案:在特殊情况下,需要在L1末尾添加新节点,而不是替换p1节点。 ```c if (p1 == NULL) // 特殊情况:L2中的元素指数L1中没有,插入新结点 { // 创建新结点 Sqlist s = (Sqlist )malloc(sizeof(Sqlist)); s->data = p2->data; // 新结点赋值 s->next = NULL;
// 找到L1的末尾 Sqlist *temp = L1; while (temp->next != NULL) { temp = temp->next; }
// 在末尾添加新节点 temp->next = s; } ```
在输出时删除系数为0的元素,可以在遍历链表并输出之前,在链表上删除系数为0的节点。在遍历过程中可以维护一个指针p_prev,指向当前节点的前一个节点,以便删除操作。 c void Displist(Sqlist *L) { Sqlist *p = L->next; Sqlist *p_prev = L; // 前一个节点指针 while (p) { if (p->data.i == 0) { // 删除p节点 p_prev->next = p->next; Sqlist *temp = p; p = p->next; free(temp); } else { if (p->data.i > 0) printf("+%dx^(%d)", p->data.i, p->data.j); else printf("%dx^(%d)", p->data.i, p->data.j); p_prev = p; p = p->next; } } }
上述是对给出的代码的改进建议,希望能帮助你解决遇到的问题。
【相关推荐】