📜  扁平化链表的 C++ 程序(1)

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

扁平化链表的 C++ 程序

在处理有向无环图或树形结构时,通常会用到链表来保存数据。然而,链表中的每个节点可能还会包含若干个子节点,这些子节点也可以是链表形式。这样的链表称为嵌套链表或多级链表。

扁平化嵌套链表是指将这个多级链表中的所有节点提取出来,按照原来链表的顺序排列成一个新的链表。本文将介绍如何用 C++ 实现一个扁平化链表的程序。

定义链表结构体

链表的节点可以用如下结构体来表示:

struct Node {
    int val;            // 保存节点的值
    Node* prev;         // 保存上一个节点指针
    Node* next;         // 保存下一个节点指针
    Node* child;        // 保存子节点指针
};

上面的 child 指针可以为空,如果有子节点,则表示这个节点是一个多级链表的头节点,其它节点可以通过 child 指针访问到它的子节点。

扁平化链表的主要算法

实现扁平化的主要算法是深度优先搜索,可以通过 DFS 来访问链表中所有的节点,然后将它们按照顺序连接到新的链表中。每次完成一个节点的访问之后,应该及时更新前驱节点的指针。

class Solution {
public:
    Node* flatten(Node* head) {
        Node* current = head;   // 记录当前访问的节点
        Node* prev = nullptr;   // 保存前驱节点指针
        stack<Node*> stk;       // 保存节点的栈

        while (current || !stk.empty()) {
            if (current == nullptr) {
                current = stk.top();
                stk.pop();
                prev->next = current;
                current->prev = prev;
            }

            if (current->child) {
                if (current->next) {
                    stk.push(current->next);
                }
                current->next = current->child;
                current->next->prev = current;
                current->child = nullptr;
            }
            prev = current;
            current = current->next;
        }

        return head;
    }
};

在上面的算法中,我们使用一个栈来保存还未遍历它的节点。如果当前节点的 child 指针存在,则将当前节点的 next 指针保存到栈中等待后面遍历。然后就可以将 child 节点作为当前节点的 next 节点处理。当遍历完一个节点时,我们将其保存成前驱节点。

测试扁平化链表的 C++ 程序

下面是针对上面实现的 C++ 程序进行的测试代码:

void printList(Node* head) {
    while (head) {
        cout << head->val << " ";
        head = head->next;
    }
    cout << endl;
}

int main() {
    /*
     * 1--2--3--4--5--6--NULL
     *          |
     *          7--8--9--NULL
     *              |
     *              10--NULL
     */
    Node a{10, nullptr, nullptr, nullptr};
    Node b{9, nullptr, &a, nullptr};
    Node c{8, nullptr, &b, nullptr};
    Node d{7, nullptr, &c, nullptr};
    Node e{6, &d, nullptr, nullptr};
    Node f{5, &e, nullptr, nullptr};
    Node g{4, &f, nullptr, nullptr};
    Node h{3, &g, nullptr, &d};
    Node i{2, &h, nullptr, nullptr};
    Node j{1, &i, nullptr, nullptr};

    Solution s;
    Node* head = s.flatten(&j);
    printList(head);    // 输出 1 2 3 4 5 6 7 8 9 10
    return 0;
}
总结

本文介绍了如何用 C++ 实现扁平化嵌套链表的程序,主要算法是深度优先搜索。我们使用一个栈来记录待遍历的节点,每次处理一个节点时,会更新前驱节点的指针,并将后面的节点保存到栈中,以便遍历完成之后再处理。通过本文的介绍,相信读者已经掌握了实现扁平化链表的基本思想和算法,可以自行定义和测试其它更复杂的链表结构。