c语言合并k个有序链表,经典算法——合并K个有序链表(示例代码)

这篇博客介绍了两种合并K个有序链表的方法:一是利用最小堆,通过创建一个大小为K的优先队列,不断取出最小值并更新队列;二是采用分治法,利用归并排序的思想,通过递归和分治将链表数组合并为有序链表。这两种方法都展示了链表操作和算法设计的有效策略。
摘要由CSDN通过智能技术生成

一、题目要求:

将K个有序链表合并为一个有序链表

二、实现方法:

方法一:利用最小堆方法

用一个大小为K的最小堆(用优先队列+自定义降序实现)(优先队列就是大顶堆,队头元素最大,自定义为降序后,就变成小顶堆,队头元素最小),先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中。

d2dfd1edb4654f958100f4f2481dfd6a.jpg

be069ab2dba34c058e2a0c5564a3c337.jpg

整体测试代码:

#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;

}

ef3d39f8f77d443fa89a885e3528da1b.jpg

方法二:分治法

利用归并排序的思想,利用递归和分治法将链表数组划分成为越来越小的半链表数组,再对半链表数组排序,最后再用递归步骤将排好序的半链表数组合并成为越来越大的有序链表。

541151de0b614876a23903407ce929bf.jpg

acd938bc42a84e3d8a7bf5f03490313a.jpg

整体测试代码:

#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;

}

815b6466064f4b95b6dbeb5034e32ee0.jpg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值