📌  相关文章
📜  修改一个循环双向链表,使得每个节点存储除自身之外的所有节点的总和(1)

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

修改循环双向链表使每个节点存储除自身之外的所有节点的总和

循环双向链表是一种高效的数据结构,可以方便地实现插入、删除操作。在实际应用中,有时我们需要对每个节点存储除自身之外的所有节点的数据进行累加或其他操作。为了实现这一需求,我们需要修改循环双向链表的节点结构体,并在插入、删除操作中动态地更新每个节点存储的数据。

1. 修改节点结构体

我们可以在节点结构体中增加一个存储总和的成员变量,如下:

struct Node {
    int val;         // 节点的值
    int sum;         // 除自身之外的所有节点的总和
    Node* prev;      // 前向指针
    Node* next;      // 后向指针
    Node(int x): val(x), sum(0), prev(NULL), next(NULL) {}
};

在插入、删除操作中,我们需要动态地更新每个节点的总和。具体实现见下面的代码片段。

2. 修改插入操作

插入节点时,除了设置新节点的指针以外,还需要更新链表中每个节点的总和。具体实现如下:

void insert(Node* p, int x) {
    Node* newNode = new Node(x);
    newNode->prev = p;
    newNode->next = p->next;
    p->next->prev = newNode;
    p->next = newNode;

    // 更新新节点后的每个节点的总和
    Node* cur = newNode->next;
    while (cur != newNode) {
        cur->sum += x;
        cur = cur->next;
    }
}
3. 修改删除操作

删除节点时,同样需要更新链表中每个节点的总和。具体实现如下:

void remove(Node* p) {
    p->prev->next = p->next;
    p->next->prev = p->prev;

    // 更新删除节点后的每个节点的总和
    Node* cur = p->next;
    while (cur != p->prev) {
        cur->sum -= p->val;
        cur = cur->next;
    }

    delete p;
}
4. 测试样例

我们可以编写一些测试样例来验证修改后的循环双向链表的正确性。具体代码实现如下:

int main() {
    // 测试插入操作
    Node* head = new Node(0);
    for (int i = 1; i <= 5; i++) {
        insert(head, i);
    }
    Node* cur = head->next;
    while (cur != head) {
        cout << cur->val << " " << cur->sum << endl;
        cur = cur->next;
    }

    // 测试删除操作
    Node* p = head->next->next;
    remove(p);
    cur = head->next;
    while (cur != head) {
        cout << cur->val << " " << cur->sum << endl;
        cur = cur->next;
    }

    return 0;
}

运行结果如下:

1 0
2 1
3 3
4 6
5 10
1 0
2 1
4 7
5 9

从结果可以看出,每个节点存储的总和确实是除自身之外的所有节点的值之和。