📜  从2D矩阵构造双链链表(1)

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

从2D矩阵构造双链链表

双链表是一种常用的数据结构,它可以快速地在中间位置插入和删除元素。在实际开发中,我们有时需要从一个二维矩阵中构造双链表,本文将介绍如何实现这一过程。

分析

假设我们有一个 $n \times m$ 的矩阵 $a$,我们要将它构造成一个双链表。这里我们将矩阵各元素(下标从 $0$ 开始)的双链表节点编号从 $0$ 开始依次为 $0, 1, \cdots, nm-1$。节点编号与矩阵中行列的关系为 $id = i \times m + j$。那么对于每个节点 $i$,它所在位置的矩阵元素的下标为 $(\lfloor i/m \rfloor, i\ \mathrm{mod}\ m)$。

我们需要构造每个节点的前驱和后继指针,以便快速实现节点的插入和删除。根据节点编号与矩阵元素下标的关系,我们可以把一个节点编号拆分为两部分,一部分是矩阵元素的行号,一部分是矩阵元素的列号。

对于第 $i$ 个节点,它的前驱编号为 $i-1$,后继编号为 $i+1$。但是这种方式会在矩阵的行末和列末出现问题——即最后一列的后继不是下一个节点,最后一行的后继也不是下一个节点。所以我们需要在构造过程中特判这种情况。

代码

我们以 C++ 语言为例,给出从二维矩阵构造双链表的实现代码。代码中,我们使用了 struct 结构体来表示链表节点,每个节点包括一个存储的值 val 和两个指向前驱和后继节点的指针 prevnext

struct Node {
    int val;
    Node *prev, *next;
    Node(int v) : val(v), prev(nullptr), next(nullptr) {}
};

Node* constructListFromMatrix(std::vector<std::vector<int>>& a) {
    int n = a.size(), m = a[0].size();
    Node* head = new Node(0);
    Node* tail = head;
    for (int i = 0; i < n * m; ++i) {
        int x = i / m, y = i % m;
        Node* node = new Node(a[x][y]);
        if (x == 0 && y == 0) {
            head->next = node;
            node->prev = head;
        }
        tail->next = node;
        node->prev = tail;
        tail = node;
        if (y == m - 1) {
            tail->next = new Node(0);
            tail->next->prev = tail;
            tail = tail->next;
        }
    }
    return head->next;
}
结语

本文给出了从二维矩阵构造双链表的实现思路和代码。程序员在实际开发中可以根据自己的需求进行相应的修改和优化。