一、题目要求:
将K个有序链表合并为一个有序链表
二、实现方法:
方法一:利用最小堆方法
用一个大小为K的最小堆(用优先队列+自定义降序实现)(优先队列就是大顶堆,队头元素最大,自定义为降序后,就变成小顶堆,队头元素最小),先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中。
整体测试代码:
#include
#include
#include
#include
#include // std::greater
using namespace std;
struct ListNode
{
int val;
ListNode* next;
};
struct cmp
{
bool operator()(ListNode* a, ListNode* b)
{
return a->val > b->val;
}
};
//方法一:利用最小堆方法
//用一个大小为K的最小堆(用优先队列+自定义降序实现)(优先队列就是大顶堆,队头元素最大,自定义为降序后,就变成小顶堆,队头元素最小),
//先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中。
ListNode* mergeKLists2(vector lists)
{
if (lists.size() == 0) return NULL;
priority_queue, cmp> heap;
for (int i = 0; i < lists.size(); ++i)
{
heap.push(lists[i]);
}
ListNode* newHead=NULL;
ListNode* p=NULL;
ListNode* q=NULL;
while (!heap.empty())
{
q = heap.top();
heap.pop();
if (q->next != NULL) heap.push(q->next);
if (newHead == NULL)
{
newHead = q;
p = q;
}
else
{
p->next = q;
p = p->next;
}
}
return newHead;
}
ListNode* CreateListNode(int value)
{
ListNode* pNode = new ListNode();
pNode->val = value;
pNode->next = NULL;
return pNode;
}
void DestroyList(ListNode* pHead)
{
ListNode* pNode = pHead;
while (pNode != NULL)
{
pHead = pHead->next;
delete pNode;
pNode = pHead;
}
}
void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
if (pCurrent == NULL)
{
printf("Error to connect two nodes.\\n");
exit(1);
}
pCurrent->next = pNext;
}
int main()
{
vector lists;
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(2);
ListNode* pNode6 = CreateListNode(3);
ListNode* pNode7 = CreateListNode(4);
ListNode* pNode8 = CreateListNode(5);
ListNode* pNode9 = CreateListNode(6);
ListNode* pNode10 = CreateListNode(7);
ListNode* pNode11 = CreateListNode(8);
ListNode* pNode12 = CreateListNode(9);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ConnectListNodes(pNode7, pNode8);
ConnectListNodes(pNode9, pNode10);
ConnectListNodes(pNode10, pNode11);
ConnectListNodes(pNode11, pNode12);
ListNode* L1 = pNode1;
ListNode* L2 = pNode5;
ListNode* L3 = pNode9;
cout << "链表l1: ";
while (L1)
{
cout << L1->val << " ";
L1 = L1->next;
}
cout << endl;
cout << "链表l2: ";
while (L2)
{
cout << L2->val << " ";
L2 = L2->next;
}
cout << endl;
cout << "链表l3: ";
while (L3)
{
cout << L3->val << " ";
L3 = L3->next;
}
cout << endl;
lists.push_back(pNode1);
lists.push_back(pNode5);
lists.push_back(pNode9);
ListNode* res = mergeKLists2(lists);
cout << "合并后链表: ";
while (res)
{
cout << res->val << " ";
res = res->next;
}
cout << endl;
system("pause");
DestroyList(res);
return 0;
}
方法二:分治法
利用归并排序的思想,利用递归和分治法将链表数组划分成为越来越小的半链表数组,再对半链表数组排序,最后再用递归步骤将排好序的半链表数组合并成为越来越大的有序链表。
整体测试代码:
#include
#include
using namespace std;
struct ListNode
{
int val;
ListNode* next;
};
//方法二:分治法
//利用归并排序的思想,利用递归和分治法将链表数组划分成为越来越小的半链表数组,
//再对半链表数组排序,最后再用递归步骤将排好序的半链表数组合并成为越来越大的有序链表
ListNode* mergeKLists(vector lists, int K)
{
return mergeLists(lists, 0, K);
}
ListNode* mergeLists(vector listNodes, int low, int high)
{
if (low == high) return NULL;
if (high - low == 1) return listNodes[low];
if (high - low == 2) return merge2(listNodes[low], listNodes[high - 1]);
int mid = (high + low) / 2;
ListNode* a = mergeLists(listNodes, low, mid);
ListNode* b = mergeLists(listNodes, mid, high);
return merge2(a, b);
}
ListNode* merge2(ListNode* L1, ListNode* L2)
{
if (L1 == NULL && L2 == NULL) return NULL;
else if (L1 == NULL) return L2;
else if (L2 == NULL) return L1;
ListNode* newHead = NULL;
ListNode* p = NULL;
if (L1->val < L2->val){ newHead = L1; p = L1; L1 = L1->next; }
else{ newHead = L2; p = L2; L2 = L2->next; }
while (L1 != NULL && L2 != NULL)
{
if (L1->val < L2->val)
{
p->next = L1;
L1 = L1->next;
}
else
{
p->next = L2;
L2 = L2->next;
}
p = p->next;
}
p->next = L1 ? L1 : L2;
return newHead;
}
ListNode* CreateListNode(int value)
{
ListNode* pNode = new ListNode();
pNode->val = value;
pNode->next = NULL;
return pNode;
}
void DestroyList(ListNode* pHead)
{
ListNode* pNode = pHead;
while (pNode != NULL)
{
pHead = pHead->next;
delete pNode;
pNode = pHead;
}
}
void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
if (pCurrent == NULL)
{
printf("Error to connect two nodes.\\n");
exit(1);
}
pCurrent->next = pNext;
}
int main()
{
vector lists;
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(2);
ListNode* pNode6 = CreateListNode(3);
ListNode* pNode7 = CreateListNode(4);
ListNode* pNode8 = CreateListNode(5);
ListNode* pNode9 = CreateListNode(6);
ListNode* pNode10 = CreateListNode(7);
ListNode* pNode11 = CreateListNode(8);
ListNode* pNode12 = CreateListNode(9);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7);
ConnectListNodes(pNode7, pNode8);
ConnectListNodes(pNode9, pNode10);
ConnectListNodes(pNode10, pNode11);
ConnectListNodes(pNode11, pNode12);
ListNode* L1 = pNode1;
ListNode* L2 = pNode5;
ListNode* L3 = pNode9;
cout << "链表l1: ";
while (L1)
{
cout << L1->val << " ";
L1 = L1->next;
}
cout << endl;
cout << "链表l2: ";
while (L2)
{
cout << L2->val << " ";
L2 = L2->next;
}
cout << endl;
cout << "链表l3: ";
while (L3)
{
cout << L3->val << " ";
L3 = L3->next;
}
cout << endl;
lists.push_back(pNode1);
lists.push_back(pNode5);
lists.push_back(pNode9);
ListNode* res = mergeKLists(lists, 3);
cout << "合并后链表: ";
while (res)
{
cout << res->val << " ";
res = res->next;
}
cout << endl;
system("pause");
DestroyList(res);
return 0;
}