经典算法——合并K个有序链表
来源:互联网 发布:淘宝日用品代理 编辑:程序博客网 时间:2024/05/01 14:57
一、题目要求:
将K个有序链表合并为一个有序链表
二、实现方法:
方法一:利用最小堆方法
用一个大小为K的最小堆(用优先队列+自定义降序实现)(优先队列就是大顶堆,队头元素最大,自定义为降序后,就变成小顶堆,队头元素最小),先把K个链表的头结点放入堆中,每次取堆顶元素,然后将堆顶元素所在链表的下一个结点加入堆中。
整体测试代码:
#include <vector>#include <iostream>#include<queue>#include<set>#include <functional> // std::greaterusing 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<ListNode*> lists){if (lists.size() == 0) return NULL;priority_queue<int, vector<ListNode*>, 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<ListNode*> 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 <iostream>#include <vector>using namespace std;struct ListNode{int val;ListNode* next;};//方法二:分治法//利用归并排序的思想,利用递归和分治法将链表数组划分成为越来越小的半链表数组,//再对半链表数组排序,最后再用递归步骤将排好序的半链表数组合并成为越来越大的有序链表ListNode* mergeKLists(vector<ListNode*> lists, int K){return mergeLists(lists, 0, K);}ListNode* mergeLists(vector<ListNode*> 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<ListNode*> 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;}
1 0
- 经典算法——合并K个有序链表
- 经典算法——合并两个有序链表
- 经典算法学习——合并两个有序链表
- LeetCode 合并k个有序链表
- 合并k个有序链表
- 合并k个有序链表
- 合并K个有序链表
- 合并k个有序的链表
- 合并k个有序链表 Merge k Sorted Lists
- 算法导论6.5-9,K个有序链表合并 nlgn
- 【算法】合并k个有序的链表-基于最小堆的思想
- C++经典算法————有序链表合并
- O(N lgK) 时间内合并K个有序链表
- O(N lgK) 时间内合并K个有序链表
- 合并K个有序链表O(N lgK)
- 合并K个有序链表-堆的使用
- O(N lgK) 时间内合并K个有序链表
- 23.合并k个有序表
- Java常用排序算法之选择排序
- mapreduce采用多进程与spark采用多线程比较
- Javascript对象定义的几种方式
- hdu5672 string(尺取法)
- 编译原理之后缀表达式生成与计算(2)
- 经典算法——合并K个有序链表
- centos6.5上NFS服务器搭建
- 手机开发实战50——CALL介绍
- 第13周项目2:动物这样叫(1)
- Poj1745 Divisibility
- keras实现deepid:flatten中间层、merge多个层次、二维图像的处理、权重的保存与重用、Autoencoder
- viewPager+photoView实现图片轮播和手势缩放功能 支持手势缩放的imageView 如何实现相册左右滑动和手势缩放 如何让图片自适应控件大小 photoView如何使用(上)
- Imageloader配置和设置圆形
- 手机开发实战51——SMS介绍1