超详细讲解线性结构中用链表实现多项式的相加【c语言实现】

首先定义一个链表结构

// 定义链表节点的结构
struct PolyNode
{
    int coef; // 系数
    int expon; // 指数
    struct PolyNode* link; // 链接到下一个节点
};
// 创建指针类型的别名
typedef struct PolyNode* Polynomial;

link是指向下一个节点的指针


创建新节点

// 创建新节点
Polynomial createNode(int coef, int expon)
{
    Polynomial newNode = (Polynomial)malloc(sizeof(struct PolyNode));
    newNode->coef = coef;//初始化节点的系数
    newNode->expon = expon;//初始化节点的指数
    newNode->link = NULL;初始化节点的链接为 NULL,表示没有下一个节点
    return newNode;
}

1.malloc函数

第三行中malloc函数用于在堆上分配一块内存,大小由其参数指定,并返回一个指向该内存块的指针。原型如下:

void* malloc(size_t size);
  • 参数

    • size_t size:要分配的内存块的大小,以字节为单位。
  • 返回值

    • 返回一个指向分配的内存块的指针,如果内存分配失败,则返回 NULL

2.sizeof(struct PolyNode)

计算 struct PolyNode 结构体的大小(即包含所有成员变量的总大小)。

3.类型转换 (Polynomial)

由于 malloc 返回的是一个 void* 类型的指针,需要将其转换为适当的类型。在这里,Polynomial 被定义为 struct PolyNode* 的别名。

typedef struct PolyNode* Polynomial;

因此,类型转换 (Polynomial) 实际上是 (struct PolyNode*),将 void* 类型的指针转换为指向 struct PolyNode 的指针。

newNode->link = NULL;

为什么需要 newNode->link = NULL;

  • 表示终止节点
    • 在链表中,最后一个节点的 link 应该为 NULL,表示链表的结束。
  • 避免指针悬挂
    • 初始化 linkNULL 可以避免指针悬挂(dangling pointer),即指针指向未定义的位置。
  • 简化操作
    • 在链表的后续操作中,如果节点的 link 已经初始化为 NULL,可以更方便地判断节点是否为链表的终止节点。

插入新节点

Polynomial insertNode(Polynomial head, int coef, int expon)
{
    Polynomial newNode = createNode(coef, expon);
    if (head == NULL || head->expon < expon)
    {
        newNode->link = head;
        return newNode;
    }

    Polynomial current = head;
    while (current->link != NULL && current->link->expon > expon)
    {
        current = current->link;
    }

    newNode->link = current->link;
    current->link = newNode;

    return head;
}
Polynomial insertNode(Polynomial head, int coef, int expon)

函数的定义:

参数

  • head:指向链表头节点的指针。
  • coef:新节点的系数。
  • expon:新节点的指数。

返回值

  • 返回新的链表头指针
Polynomial newNode = createNode(coef, expon);//创造新节点

调用 createNode 函数创建一个新节点,初始化其 coefexpon,并将 link 设为 NULL

//处理特殊情况
if (head == NULL || head->expon < expon)
{
    newNode->link = head;
    return newNode;
}
  • 如果链表为空 (head == NULL) 或新节点的指数大于当前头节点的指数(head->expon < expon),则将新节点插入到链表的头部。
  • 新节点的 link 指向当前头节点,然后返回新节点作为新的头节点。
//插入节点到链表中间或末尾
Polynomial current = head;
while (current->link != NULL && current->link->expon > expon)
{
    current = current->link;
}
  • 从头节点开始,遍历链表,找到第一个 current->link->expon 小于或等于新节点指数的位置。
  • 遍历条件是 current->link != NULL 并且 current->link->expon > expon

//插入新节点
newNode->link = current->link;
current->link = newNode;
  • 将新节点的 link 指向 current 的下一个节点。(current->link表示当前节点的下一节点)
  • currentlink 更新为新节点,这样就将新节点插入到了链表中。

打印多项式

void printPolynomial(Polynomial poly)
{
    while (poly != NULL)
    {
        printf("%dx^%d", poly->coef, poly->expon);
        if (poly->link != NULL)
        {
            printf(" + ");
        }
        poly = poly->link;
    }
    printf("\n");
}

遍历链表打印出各个节点的值


释放多项式

// 释放多项式
void freePolynomial(Polynomial poly)
{
    while (poly != NULL)
    {
        Polynomial temp = poly;
        poly = poly->link;
        free(temp);
    }
}

在释放多项式的过程中,poly = poly->link; 这一行代码的作用是移动指针 poly 到下一个节点。这样做的目的是确保在释放当前节点 temp 之后,poly 指向的是下一个节点,而不会丢失对链表剩余部分的引用。

具体来说,freePolynomial 函数的工作原理如下:

  1. 初始化

    • 开始时,poly 指向链表的头节点。
  2. 循环遍历链表

    • 在每次循环迭代中,保存当前节点的指针到 temp
    • poly 移动到下一个节点 poly->link
    • 释放 temp 所指向的当前节点的内存。
  3. 循环终止

    • polyNULL 时,说明链表已经遍历完毕,所有节点的内存都已被释放。

多项式求和

Polynomial addPolymials(Polynomial poly1, Polynomial poly2)
{
    Polynomial result = NULL;
    while (poly1 != NULL && poly2 != NULL)
    {
        if (poly1->expon > poly2->expon)
        {
            result = insertNode(result, poly1->coef, poly1->expon);
            poly1 = poly1->link;
        }
        else if (poly1->expon < poly2->expon)
        {
            result = insertNode(result, poly2->coef, poly2->expon);
            poly2 = poly2->link;
        }
        else
        {
            int sum = poly1->coef + poly2->coef;
            if (sum != 0)
            {
                result = insertNode(result, sum, poly1->expon);

            }
            poly1 = poly1->link;
            poly2 = poly2->link;
        }
    }
    return result;
}

详细解释

  1. 创建新节点

    • createNode 函数用于分配新节点的内存并初始化其成员。
  2. 插入新节点

    • insertNode 函数用于将新节点按指数降序插入到链表中。
  3. 打印多项式

    • printPolynomial 函数用于打印链表中的每个节点。
  4. 释放多项式内存

    • freePolynomial 函数用于释放链表节点的内存。
  5. 多项式相加

    • addPolynomials 函数用于相加两个多项式,并返回结果多项式。

多项式相加逻辑

  1. 遍历两个多项式

    • 使用 while 循环遍历 poly1poly2,比较每个节点的指数。
  2. 比较指数

    • 如果 poly1->expon > poly2->expon,将 poly1 的节点加入结果链表。
    • 如果 poly1->expon < poly2->expon,将 poly2 的节点加入结果链表。
    • 如果 poly1->expon == poly2->expon,将两个系数相加,如果和不为零,将新节点加入结果链表。
  3. 处理剩余节点

    • 如果 poly1 还有剩余节点,全部加入结果链表。
    • 如果 poly2 还有剩余节点,全部加入结果链表。

主函数

int main()
{
    Polynomial poly1 = NULL;
    poly1 = insertNode(poly1, 5, 2);
    poly1 = insertNode(poly1, 4, 1);
    poly1 = insertNode(poly1, 3, 0);

    Polynomial poly2 = NULL;
    poly2 = insertNode(poly2, 3, 3);
    poly2 = insertNode(poly2, 2, 1);
    poly2 = insertNode(poly2, 1, 0);

    printf("Polynomial 1: ");
    printPolynomial(poly1);

    printf("Polynomial 2: ");
    printPolynomial(poly2);


    Polynomial poly3 = NULL;

    printf("Sum Polynomial: ");

    poly3 = addPolymials(poly1, poly2);
    printPolynomial(poly3);


    freePolynomial(poly1);
    freePolynomial(poly2);
    freePolynomial(poly3);
    return 0;
}

运行结果图

完整代码

#include <stdio.h>
#include <stdlib.h>

// 定义链表节点的结构
struct PolyNode
{
    int coef; // 系数
    int expon; // 指数
    struct PolyNode* link; // 链接到下一个节点
};

// 创建指针类型的别名
typedef struct PolyNode* Polynomial;

// 创建新节点
Polynomial createNode(int coef, int expon)
{
    Polynomial newNode = (Polynomial)malloc(sizeof(struct PolyNode));
    newNode->coef = coef;
    newNode->expon = expon;
    newNode->link = NULL;
    return newNode;
}

// 插入节点(按指数降序排列)
Polynomial insertNode(Polynomial head, int coef, int expon)
{
    Polynomial newNode = createNode(coef, expon);
    if (head == NULL || head->expon < expon)
    {
        newNode->link = head;
        return newNode;
    }
    Polynomial current = head;
    while (current->link != NULL && current->link->expon > expon)
    {
        current = current->link;
    }

    newNode->link = current->link;
    current->link = newNode;

    return head;
}

// 打印多项式
void printPolynomial(Polynomial poly)
{
    while (poly != NULL)
    {
        printf("%dx^%d", poly->coef, poly->expon);
        if (poly->link != NULL)
        {
            printf(" + ");
        }
        poly = poly->link;
    }
    printf("\n");
}

// 释放多项式
void freePolynomial(Polynomial poly)
{
    while (poly != NULL)
    {
        Polynomial temp = poly;
        poly = poly->link;
        free(temp);
    }
}
Polynomial addPolymials(Polynomial poly1, Polynomial poly2)
{
    Polynomial result = NULL;
    while (poly1 != NULL && poly2 != NULL)
    {
        if (poly1->expon > poly2->expon)
        {
            result = insertNode(result, poly1->coef, poly1->expon);
            poly1 = poly1->link;
        }
        else if (poly1->expon < poly2->expon)
        {
            result = insertNode(result, poly2->coef, poly2->expon);
            poly2 = poly2->link;
        }
        else
        {
            int sum = poly1->coef + poly2->coef;
            if (sum != 0)
            {
                result = insertNode(result, sum, poly1->expon);

            }
            poly1 = poly1->link;
            poly2 = poly2->link;
        }
    }
    return result;
}
int main()
{
    Polynomial poly1 = NULL;
    poly1 = insertNode(poly1, 5, 2);
    poly1 = insertNode(poly1, 4, 1);
    poly1 = insertNode(poly1, 3, 0);

    Polynomial poly2 = NULL;
    poly2 = insertNode(poly2, 3, 3);
    poly2 = insertNode(poly2, 2, 1);
    poly2 = insertNode(poly2, 1, 0);

    printf("Polynomial 1: ");
    printPolynomial(poly1);

    printf("Polynomial 2: ");
    printPolynomial(poly2);


    Polynomial poly3 = NULL;

    printf("Sum Polynomial: ");

    poly3 = addPolymials(poly1, poly2);
    printPolynomial(poly3);


    freePolynomial(poly1);
    freePolynomial(poly2);
    freePolynomial(poly3);
    return 0;
}

如果感觉有帮助,点个赞呗!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘子O柠檬一样酸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值