题目:请设计一个时间复杂度为O(nlgk)的算法,它能够将k个有序链表合并为一个有序链表,这里n是所有输入链表包含 的总的元素个数。
(提示:使用最小堆完成k路归并)
思路:建一个大小为k的堆,堆中的每个元素代表一个List,元素的key为List当前最小元素的值,调整为最小堆,取出堆顶的元素,并记录到排序结果中,然后插入相应List中下一个元素的值作为新的堆顶元素key的值,然后调整堆为最小堆,并记录到排序结果中,如果该List没有下一个元素要插入,就删除List所在的结点,然后调整堆为最小堆,依次进行下去,直到n个元素归并完毕。
C++实现如下:
#include <iostream>
#include <vector>
using namespace std;
#include <stdlib.h>
#include "Exercise6_5_8.h"
#include "Heap.h"
#define K 10
#define DATA_COUNT 100
ostream& operator<<(ostream & s, const node & n)
{
s << n.value;
return s;
}
//5个链表,每个链表的头结点放入Head中
int mergeResult[DATA_COUNT+1] = {0};
CMaxHeap<node> H(K, node::getMaxNode());
vector<ARRAY> buildTestData();
void showTestData(vector<ARRAY> inputParam);
void insertListHeadToHeap(vector<ARRAY> &inputParam, int listIndex);
void showResult();
void recordMergeResult(int data);
ARRAY solve_6_5_8(vector<ARRAY> inputParam);
int K_Merge_6_5_8()
{
vector<ARRAY> inputParam = buildTestData();
showTestData(inputParam);
ARRAY result = solve_6_5_8(inputParam);
showResult();
return 0;
}
ARRAY solve_6_5_8(vector<ARRAY> inputParam)
{
ARRAY ret;
while(H.isEmpty() == false)
H.extract();
for(int i = 0; i < inputParam.size(); i++)
insertListHeadToHeap(inputParam, i);
while(H.isEmpty() == false)
{
node top = H.extract();
ret.push_back(top);
insertListHeadToHeap(inputParam, top.list);
}
return ret;
}
vector<ARRAY> buildTestData()
{
int value, list;
//构造需要合并的数据
vector<ARRAY > ret(K);
for(value = DATA_COUNT; value >0; value--)
{
list = rand() % K;
node newNode;// = {list, value};
newNode.list = list;
newNode.value = value;
ret[list].push_back(newNode);
}
return ret;
}
void showTestData(vector<ARRAY> inputParam)
{
cout<<"显示待排序数据"<<endl;
for(int i = 0; i < inputParam.size(); i++)
{
ARRAY array = inputParam[i];
for(int j = 0; j < array.size(); j++)
cout<<array[j].value<<' ';
cout<<endl;
}
}
void insertListHeadToHeap(vector<ARRAY> &inputParam, int listIndex)
{
ARRAY &array = inputParam[listIndex];
if(array.size() != 0)
{
H.insert(array[0]);
array.erase(array.begin());
}
}
void showResult()
{
//输出合并结果
cout<<"输出合并结果"<<endl;
for(int i = 1; i <= mergeResult[0];i++)
cout<<mergeResult[i]<<' ';
cout<<endl;
}
void recordMergeResult(int data)
{
mergeResult[++mergeResult[0]] = data;
}
代码参考:
http://blog.csdn.net/mishifangxiangdefeng/article/details/7668486