C++——合并k个有序链表

C++——合并k个有序链表_第1张图片

对于合并k个有序链表,可以先看一下合并两个有序链表的思想,(点这里)

对于k个链表的合并,我们可以基于两个有序链表的合并思想,先将两个链表合并为一个链表,再将得到的结果链表与第三个链表合并为一个链表,以此类推,最终将k个链表合并为一个有序链表。

本篇不在累述这种方法,对于k个有序链表,我们可以考虑优先队列,首先将所有链表入队,然后重载比较操作符,用于构建链表节点的小根堆,依次取出队首节点,得到的新的链表就是一个有序的链表。

这里有两个点需要注意:

1.我们优先队列中的是一个个链表,而每次队首最小值就是当前这个链表的头节点的值,我们获得该头节点,并让队首元素出队,此时,出队的是整个链表,因此我们需要判断当前最小节点的下一个节点是否为空,不为空则说明后面还有节点,我们需要把下一个节点重新入队,参与排序。比如[{1,5,6},{2,4}] 我们让第一个链表出队了,获得了最小的头节点(值为1的),但后面的5-6需要重新入队参与排序。

2.优先队列默认为大根堆,且入队的类型是链表,已定义的排序函数不能满足需求,所以我们需要重载比较函数,虽然是链表类型,但我们每次只需要比较每个链表的当前头节点的值大小即可。

参考代码阅读,很好理解,代码如下:

struct com{
    bool operator()(ListNode* node1,ListNode* node2)
    {
        return node1->val>node2->val;
    }
};
class Solution {
public:
    ListNode *mergeKLists(vector &lists) {
        ListNode* head=new ListNode(-1);
        ListNode* res=head;
        if(lists.size()==0) return nullptr;
        priority_queue,com>pq;
        for(ListNode* node:lists)
            if(node!=nullptr)
                pq.push(node);
        while(!pq.empty())
        {
            ListNode* min=pq.top();
            head->next=min;
            head=min;
            pq.pop();
            if(min->next!=nullptr)
                pq.push(min->next);
        }
        return res->next;
    }
};

 

你可能感兴趣的:(C++,合并链表,k个有序链表,C++)