算导--6.5-9使用最小堆完成k路归并问题

题目:请设计一个时间复杂度为O(nlgk)的算法,它能够将k个有序链表合并为一个有序链表,这里n是所有输入链表包含 的总的元素个数。

(提示:使用最小堆完成k路归并)

思路:建一个大小为k的堆,堆中的每个元素代表一个List,元素的key为List当前最小元素的值,调整为最小堆,取出堆顶的元素,并记录到排序结果中,然后插入相应List中下一个元素的值作为新的堆顶元素key的值,然后调整堆为最小堆,并记录到排序结果中,如果该List没有下一个元素要插入,就删除List所在的结点,然后调整堆为最小堆,依次进行下去,直到n个元素归并完毕。

C++实现如下:

#include 
#include 
using namespace std;

#include 

#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 H(K, node::getMaxNode());

vector buildTestData();
void showTestData(vector inputParam);
void insertListHeadToHeap(vector &inputParam, int listIndex);
void showResult();
void recordMergeResult(int data);
ARRAY solve_6_5_8(vector inputParam);

int K_Merge_6_5_8()
{
	vector inputParam = buildTestData();
	showTestData(inputParam);

	ARRAY result = solve_6_5_8(inputParam);

	showResult();
	return 0;
}

ARRAY solve_6_5_8(vector 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 buildTestData()
{
	int value, list;
		//构造需要合并的数据
	vector 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 inputParam)
{
	cout<<"显示待排序数据"< &inputParam, int  listIndex)
{
	ARRAY &array = inputParam[listIndex];
	if(array.size() != 0)
	{
		H.insert(array[0]);
		array.erase(array.begin());
	}
}

void showResult()
{
	//输出合并结果
	cout<<"输出合并结果"<
代码参考: http://blog.csdn.net/mishifangxiangdefeng/article/details/7668486


你可能感兴趣的:(algorithm)