数据结构多项式的运算

多项式运算我用的方法是直接在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);
}

下面是我的运行结果(很显然是错误的):

img


有哪位可以帮助一下我,万分感谢~

【以下回答由 GPT 生成】

优化多项式运算算法可以考虑以下几点改进建议:

  1. 问题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. 问题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; } ```

  3. 在输出时删除系数为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; } } }

上述是对给出的代码的改进建议,希望能帮助你解决遇到的问题。



【相关推荐】


  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7675131
  • 除此之外, 这篇博客: C语言实现八大排序算法详解及其性能之间的中的 名字已经暴露了他的算法,就是往里面插入数据,就拿我们生活中的例子来说,打扑克牌。我们往手里码牌的时候,是一张一张的码,先码一张,抓手心,不需要修改位置,因为只有一张牌,一定是有序的。再接一张,和手里的牌对比大小,调整位置,选择放在它的左边或者右边。然后接着码,又接到一张牌,拿到先和右边的牌比,比右边还大就放到最右边,如果比右边这张小呢,在和左边这张比。同样,我们这里也是这样的,首先我们默认第一个元素,一定是有序,OK吧。然后第二个,元素比较,大,放到左边,小放到右边。然后第三个元素,直到第N个,比它前一个大,继续往前找位置,直到找到对应位置了,就是有序数列了。(当然每次找位置都是在一个有序的序列中找,所以完全可以用二分查找找位置,数据大的话,二分明显快于我们一张一张比) 部分也许能够解决你的问题。

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^