当前位置: 首页 > news >正文

数据结构之多项式相加的链表实现

在计算机科学中,多项式的表示和运算经常会用到。使用链表来表示多项式是一种常见且有效的方法,它可以方便地处理多项式的各项,并且在进行多项式相加等运算时具有较好的灵活性。

多项式通常由一系列的项组成,每一项包含一个系数和一个指数。在链表中,我们可以将每一项表示为一个节点,节点包含系数、指数和指向下一个节点的指针。通过这种方式,我们可以将多项式的各项连接起来,形成一个链表。 

代码实现:

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

// 定义多项式节点结构体
typedef struct node {
    float coef;  // 系数
    int expn;    // 指数
    struct node *next;  // 指向下一个节点的指针
} node, *polynomial;

// 创建多项式链表,按照指数升序插入节点
polynomial createPolyn(int n) {
    polynomial L = (polynomial)malloc(sizeof(node));  // 分配头节点内存
    if (L == NULL) {
        fprintf(stderr, "内存分配失败\n");  // 检查内存分配是否成功
        exit(EXIT_FAILURE);
    }
    L->next = NULL;  // 初始化头节点的 next 指针为 NULL
    node *p = L;  // 用于遍历链表的指针

    printf("\n请输入多项式的系数和指数(格式:系数,指数):\n");
    for (int i = 1; i <= n; i++) {
        node *s = (node *)malloc(sizeof(node));  // 为新节点分配内存
        if (s == NULL) {
            fprintf(stderr, "内存分配失败\n");  // 检查内存分配是否成功
            exit(EXIT_FAILURE);
        }
        if (scanf("%f,%d", &s->coef, &s->expn) != 2) {  // 读取用户输入
            fprintf(stderr, "输入格式错误,请输入正确的格式(系数,指数)\n");
            exit(EXIT_FAILURE);
        }

        node *pre = p;  // 用于记录当前节点的前一个节点
        node *q = pre->next;  // 用于遍历链表的指针

        // 找到合适的插入位置,保证链表按指数升序排列
        while (q && q->expn < s->expn) {
            pre = q;
            q = q->next;
        }

        s->next = q;  // 插入新节点
        pre->next = s;
    }
    return L;
}

// 多项式相加函数
void addPolyn(polynomial L1, polynomial L2) {
    node *p1 = L1->next;  // 指向第一个多项式的第一个节点
    node *p2 = L2->next;  // 指向第二个多项式的第一个节点
    node *p3 = L1;  // 用于构建结果多项式的指针
    float sum;

    while (p1 && p2) {
        if (p1->expn == p2->expn) {
            sum = p1->coef + p2->coef;  // 系数相加
            if (sum != 0) {
                p1->coef = sum;  // 更新系数
                p3->next = p1;
                p3 = p1;
                p1 = p1->next;
                node *r = p2;
                p2 = p2->next;
                free(r);  // 释放 p2 节点的内存
            } else {
                node *r = p1;
                p1 = p1->next;
                free(r);  // 释放 p1 节点的内存
                r = p2;
                p2 = p2->next;
                free(r);  // 释放 p2 节点的内存
            }
        } else if (p1->expn < p2->expn) {
            p3->next = p1;
            p3 = p1;
            p1 = p1->next;
        } else {
            p3->next = p2;
            p3 = p2;
            p2 = p2->next;
        }
    }

    p3->next = p1 ? p1 : p2;  // 连接剩余的节点

    // 释放 L2 的头节点
    free(L2);

    node *p4 = L1->next;
    printf("\n两多项式之和: ");
    while (p4) {
        printf("%.2f,%d  ", p4->coef, p4->expn);
        p4 = p4->next;
    }
    printf("\n");
}

int main() {
    int n1, n2;
    printf("请输入第一个多项式的项数: ");
    scanf("%d", &n1);
    polynomial L1 = createPolyn(n1);  // 创建第一个多项式

    printf("请输入第二个多项式的项数: ");
    scanf("%d", &n2);
    polynomial L2 = createPolyn(n2);  // 创建第二个多项式

    addPolyn(L1, L2);  // 多项式相加

    // 释放 L1 的头节点
    free(L1);

    return 0;
}

代码结构分析:

1、结构体定义了多项式节点的基本结构,包含系数、指数和指向下一个节点的指针。使用 typedef 关键字可以方便地定义指向节点的指针类型 polynomial。

2、在创建多项式链表时,我们首先分配一个头节点,并将其 next 指针初始化为 NULL。然后,通过循环读取用户输入的系数和指数,为每一项创建一个新节点,并将其插入到链表中合适的位置,保证链表按指数升序排列。在插入节点时,我们使用两个指针 pre 和 q 来找到合适的插入位置。

3、在多项式相加的过程中,我们使用三个指针 p1、p2 和 p3 分别指向第一个多项式、第二个多项式和结果多项式。通过比较 p1 和 p2 所指向节点的指数,我们可以将它们合并到结果多项式中。如果指数相等,则将系数相加;如果相加结果不为零,则更新系数;如果相加结果为零,则删除这两个节点。最后,将剩余的节点连接到结果多项式中,并释放 L2 的头节点。

4、主函数中,我们首先读取用户输入的两个多项式的项数,然后分别创建这两个多项式。接着调用 addPolyn 函数进行多项式相加,并输出结果。最后,释放 L1 的头节点,避免内存泄漏。

总结:通过使用链表来表示多项式,并实现多项式相加的功能,我们可以更好地理解链表的操作和应用。

 运行:

 

相关文章:

  • PHP文件的导出和导入
  • 蓝桥杯省模拟赛 01串个数
  • 攻破tensorflow,勇创最佳agent(1)---学习率learning_rate问题
  • 【云服务器】在 Linux(Ubuntu / CentOS 7)上快速搭建我的世界 Minecraft 服务器,并实现远程联机,详细教程
  • 笔记:代码随想录算法训练营day62:108.冗余连接、109.冗余连接II
  • MybatisPlus(SpringBoot版)学习第四讲:常用注解
  • PHP MySQL 预处理语句
  • leetcode240.搜索二维矩阵||
  • udp通信(一)
  • VUE3+TypeScript项目,使用html2Canvas+jspdf生成PDF并实现--分页--页眉--页尾
  • 使用LLaMAFactory微调Qwen大模型
  • QT计算器开发
  • kubesphere 终端shell连不上的问题
  • FPGA Verilog/VHDl 中的锁存latch
  • leetcoed0044. 通配符匹配 hard
  • 【stm32--HAL库DMA+USART+空闲中断不定长收发数据】
  • 《探秘SQL的BETWEEN:解锁数据范围查询的深度奥秘》
  • [HCIA]网络基础
  • Canvas粒子系统终极指南:从基础运动到复杂交互的全流程实现
  • Java 环境变量配置指南
  • 4月新增社融1.16万亿,还原地方债务置换影响后信贷增速超过8%
  • 一个多月来上海交大接连“牵手”三区,在这些方面进行区校合作
  • 前四个月人民币贷款增加10.06万亿元,4月末M2余额同比增长8%
  • 颜福庆与顾临的争论:1930年代在中国维持一家医学院要花多少钱
  • 美凯龙:董事兼总经理车建兴被立案调查并留置
  • 董军同法国国防部长举行会谈