多路归并与败者树的简单实现

对于对路归并与败者树的概念参见
https://www.cnblogs.com/charlesblc/p/6138908.html
下面模拟了简单的利用败者树进行多路归并的场景

#include <iostream>
#include <vector>
#include <time.h>
#include <algorithm>

using namespace std;

//5路归并树
const int K = 5;
//最小关键字
const int MINKEY = -0x3f3f3f3f;
//最大关键字
const int MAXKEY = -MINKEY;
//表示关键字的范围

void Adjust(vector<int> &b,vector<int> &ls, int s)
{
	//调整loser树
	int t = (s + K)/2;
	while (t > 0)
	{
		if(b[s] > b[ls[t]])
		{
		//交换ls[t] 与 s 的值
			ls[t] = s ^ ls[t];
			s = s ^ ls[t];
			ls[t] = s ^ ls[t];
		}
		t /= 2;
	}
	ls[0] = s;
}


void CreatLoserTree(vector<int> &b,vector<int> &ls)
{
	b[K] = MINKEY;
	//创建失败树
	for(int i = 0; i < ls.size(); i++)
	{
		ls[i] = K;
	}
	for(int i = K-1; i >= 0; i--)
	{
		//调整每一个
		Adjust(b,ls,i);
	}
}


//多路归并与失败树
int main()
{
	
	srand((unsigned int)time(NULL));
	vector<vector<int> > vec;
	
	vector<int> ls;		//失败树
	vector<int> b;
	//存放K个关键字
	b.resize(K+1);
	ls.resize(K);
	
	//记录总的元素的个数
	int count = 0;
	
	for(int i = 0; i < K; i++)
	{
		vector<int> tmp;
		for(int j = 0; j < 20; j++)
		{
			count++;
			tmp.push_back(rand() % 100);
		}
		
		//排序
		sort(tmp.begin(),tmp.end(),greater<int>());
		
		vec.push_back(tmp);
		tmp.clear();
	}
	
	//初始化b数组,loser树中的数据项
	for(int i = 0; i < K; i++)
	{
		b[i] = vec[i].back();
		vec[i].pop_back();
	}
	
	//创建loser树
	CreatLoserTree(b,ls);
	
	vector<int> res;		//归并后的结果
	
	//取归并后的结果
	while(count > 0)
	{
		res.push_back(b[ls[0]]);
		count--;
		if(vec[ls[0]].size() == 0)
		{
			//如果一个序列变为空,则将该序列对应的loser树的位置置为最大值
			b[ls[0]] = MAXKEY;
		}
		else
		{
			//如果序列不为空,即该序列的还没有归并完,则从序列中取出一个最小值
			//加入到loser树中
			b[ls[0]] = vec[ls[0]].back();
			vec[ls[0]].pop_back();
		}
		Adjust(b,ls,ls[0]);
	}
	
	for(auto val:res)
	{
		cout << val << " ";
	}
	cout << endl;
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值