Bootstrap

priority_queue实现最小堆(C++代码演示)

在 C++ 中,可以使用 标准库中的 priority_queue 来实现最小堆。默认情况下,priority_queue 是一个最大堆,但可以通过自定义比较函数或使用 greater 来将其转换为最小堆。

以下是使用 priority_queue 实现最小堆,并解决多路归并问题的 C++ 代码


C++ 实现多路归并(最小堆)

#include <iostream>
#include <vector>
#include <queue> // 包含 priority_queue
using namespace std;

// 定义链表节点
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

// 自定义比较函数,用于实现最小堆
struct Compare {
    bool operator()(const ListNode* a, const ListNode* b) {
        return a->val > b->val; // 最小堆:小的优先级高
    }
};

// 合并 K 个有序链表
ListNode* mergeKLists(vector<ListNode*>& lists) {
    // 定义最小堆
    priority_queue<ListNode*, vector<ListNode*>, Compare> minHeap;

    // 将每个链表的头节点加入最小堆
    for (ListNode* node : lists) {
        if (node) {
            minHeap.push(node);
        }
    }

    // 虚拟头节点,用于简化链表操作
    ListNode dummy(0);
    ListNode* curr = &dummy;

    // 多路归并
    while (!minHeap.empty()) {
        // 取出堆顶元素(当前最小节点)
        ListNode* minNode = minHeap.top();
        minHeap.pop();

        // 将最小节点加入结果链表
        curr->next = minNode;
        curr = curr->next;

        // 将最小节点的下一个节点加入堆
        if (minNode->next) {
            minHeap.push(minNode->next);
        }
    }

    return dummy.next;
}

// 打印链表
void printList(ListNode* head) {
    while (head) {
        cout << head->val << " ";
        head = head->next;
    }
    cout << endl;
}

int main() {
    // 创建示例链表
    ListNode* list1 = new ListNode(1);
    list1->next = new ListNode(4);
    list1->next->next = new ListNode(5);

    ListNode* list2 = new ListNode(1);
    list2->next = new ListNode(3);
    list2->next->next = new ListNode(4);

    ListNode* list3 = new ListNode(2);
    list3->next = new ListNode(6);

    // 将链表放入 vector
    vector<ListNode*> lists = {list1, list2, list3};

    // 合并链表
    ListNode* result = mergeKLists(lists);

    // 打印结果
    printList(result); // 输出 1 1 2 3 4 4 5 6

    return 0;
}

代码解析

  1. 最小堆的实现

    • 使用 priority_queue,并自定义比较函数 Compare
    • 比较函数中,a->val > b->val 表示小的值优先级高,从而实现最小堆。
  2. 多路归并的逻辑

    • 将所有链表的头节点加入最小堆。
    • 每次从堆中取出最小节点,将其加入结果链表,并将其下一个节点加入堆。
    • 重复上述步骤,直到堆为空。
  3. 链表操作

    • 使用虚拟头节点 dummy 简化链表操作。
    • 最终返回 dummy.next 作为合并后的链表头节点。

输出结果

1 1 2 3 4 4 5 6

总结

  • 在 C++ 中,可以通过自定义比较函数或使用 greaterpriority_queue 转换为最小堆。
  • 最小堆是多路归并问题的核心数据结构,用于高效选择当前最小元素。
  • 上述代码实现了合并 K 个有序链表的功能,时间复杂度为 (O(nk \log k)),其中 (n) 是链表长度,(k) 是链表数量。
;