📜  使用循环链表添加两个多项式(1)

📅  最后修改于: 2023-12-03 15:36:39.482000             🧑  作者: Mango

使用循环链表添加两个多项式

本文将介绍使用循环链表实现多项式相加的方法。

多项式的表示

在计算机中,我们通常使用数组或链表来表示多项式。其中,链表更加灵活,能够有效地处理稀疏多项式。而循环链表是链表的一种重要扩展形式,它的最后一个节点指向第一个节点,形成了一个环。

在本文中,我们使用循环链表来表示多项式。每个节点包含三个值:系数、指数和指向下一个节点的指针。

多项式的相加

两个多项式相加的过程可以分为以下三步:

  1. 遍历两个多项式,将相同指数的项的系数相加;
  2. 将两个多项式中的剩余项相加;
  3. 将结果链表化简。

我们可以使用循环链表来实现这个过程。

构建多项式的循环链表

我们可以通过遍历原始多项式的系数数组,将每一项插入新的循环链表中。系数为0的项可以跳过。

// 定义多项式节点结构体
struct PolyNode {
    int coeff;
    int expo;
    PolyNode* next;
};

// 构建多项式循环链表
PolyNode* build_poly(int arr_coeff[], int arr_expo[], int len) {
    PolyNode* head = new PolyNode{-1, -1, nullptr};  // 创建头节点
    PolyNode* p = head;  // 定位当前节点
    for (int i = 0; i < len; i++) {
        if (arr_coeff[i] != 0) {  // 如果系数不为0
            PolyNode* node = new PolyNode{arr_coeff[i], arr_expo[i], nullptr};  // 创建当前节点
            p->next = node;  // 将当前节点插入到链表中
            p = p->next;  // 将当前节点设为最后一个节点
        }
    }
    p->next = head;  // 将最后一个节点指向头节点,形成循环链表
    return head;
}
相加多项式

我们可以遍历两个多项式的循环链表,将相同指数的项的系数相加。如果某一项的系数为0,则可以删除该节点。

// 相加两个多项式
PolyNode* add_poly(PolyNode* a, PolyNode* b) {
    PolyNode* head = new PolyNode{-1, -1, nullptr};  // 创建头节点
    PolyNode* p = head;  // 定位当前节点
    PolyNode* pa = a->next;  // 定位多项式a的当前节点
    PolyNode* pb = b->next;  // 定位多项式b的当前节点
    while (pa != a && pb != b) {  // 遍历多项式a和b
        if (pa->expo == pb->expo) {  // 如果指数相同
            int coeff = pa->coeff + pb->coeff;  // 将系数相加
            if (coeff != 0) {  // 如果系数不为0
                PolyNode* node = new PolyNode{coeff, pa->expo, nullptr};  // 创建新节点
                p->next = node;  // 将新节点插入到链表中
                p = p->next;  // 将当前节点设为最后一个节点
            }
            pa = pa->next;  // 移动多项式a的当前节点
            pb = pb->next;  // 移动多项式b的当前节点
        } else if (pa->expo > pb->expo) {  // 如果多项式a的当前项的指数大于多项式b的当前项的指数
            PolyNode* node = new PolyNode{pa->coeff, pa->expo, nullptr};  // 创建新节点
            p->next = node;  // 将新节点插入到链表中
            p = p->next;  // 将当前节点设为最后一个节点
            pa = pa->next;  // 移动多项式a的当前节点
        } else {  // 如果多项式b的当前项的指数大于多项式a的当前项的指数
            PolyNode* node = new PolyNode{pb->coeff, pb->expo, nullptr};  // 创建新节点
            p->next = node;  // 将新节点插入到链表中
            p = p->next;  // 将当前节点设为最后一个节点
            pb = pb->next;  // 移动多项式b的当前节点
        }
    }
    while (pa != a) {  // 将多项式a剩余的项插入到链表中
        PolyNode* node = new PolyNode{pa->coeff, pa->expo, nullptr};  // 创建新节点
        p->next = node;  // 将新节点插入到链表中
        p = p->next;  // 将当前节点设为最后一个节点
        pa = pa->next;  // 移动多项式a的当前节点
    }
    while (pb != b) {  // 将多项式b剩余的项插入到链表中
        PolyNode* node = new PolyNode{pb->coeff, pb->expo, nullptr};  // 创建新节点
        p->next = node;  // 将新节点插入到链表中
        p = p->next;  // 将当前节点设为最后一个节点
        pb = pb->next;  // 移动多项式b的当前节点
    }
    p->next = head;  // 将最后一个节点指向头节点,形成循环链表
    return head;
}
化简多项式

如果我们将每一项的系数相加,有可能会产生一些系数为0的项,这些项需要从链表中删除。

我们可以遍历链表,将系数为0的节点删除。

// 化简多项式
void simplify_poly(PolyNode* head) {
    PolyNode* p = head->next;  // 定位当前节点
    PolyNode* prev_p = head;  // 定位前一个节点
    while (p != head) {  // 遍历链表
        if (p->coeff == 0) {  // 如果该项的系数为0
            prev_p->next = p->next;  // 将该节点从链表中删除
            delete p;
            p = prev_p->next;  // 继续处理下一个节点
        } else {
            prev_p = p;
            p = p->next;
        }
    }
}
示例

我们可以使用以下示例测试我们刚刚编写的代码。

#include <iostream>
using namespace std;

int main() {
    int arr_coeff1[] = {1, 2, 3};
    int arr_expo1[] = {0, 1, 2};
    int arr_coeff2[] = {-1, 2, 4};
    int arr_expo2[] = {1, 2, 4};
    PolyNode* a = build_poly(arr_coeff1, arr_expo1, 3);
    PolyNode* b = build_poly(arr_coeff2, arr_expo2, 3);
    PolyNode* c = add_poly(a, b);
    simplify_poly(c);
    PolyNode* p = c->next;
    while (p != c) {
        cout << p->coeff << "x^" << p->expo;
        p = p->next;
        if (p != c) {
            cout << " + ";
        }
    }
    cout << endl;
    return 0;
}

输出结果:

4x^2 + 2x^1 + 4x^4
总结

本文介绍了使用循环链表添加两个多项式的方法,包括构建多项式的循环链表、相加多项式和化简多项式。这种方法可以有效地处理稀疏多项式,并且代码实现简单。