数据结构造轮子5.2-----基于败者树的K路归并算法

KWayMerge.h

#pragma once

#include "stdafx.h"
#include "iostream"
#include <stdlib.h>

//归并段数
#define K 5

//每个并归段数据数量
#define MAX_DATA_NUM 10

//最大关键字
#define MAX_KEY 9999

//最小关键字
#define MIN_KEY -1


class KWayMerge
{
public:
	int * loser_tree;
	int * leaf_node;

	//储存各个并归列的数据
	//key为下一个并归的位置
	struct
	{
		int data[MAX_DATA_NUM];
		int key;
	}data_sector[K];

	void ImportMessage();
	void KWayMergeSort();
	void LoadData(int leaf_pos);
	void InitKWayMerge();
	void CreateLoserTree();
	void AdjustLoserTree(int leaf_pos);
};

KWayMerge.cpp

#include "stdafx.h"
#include "KWayMerge.h"

using namespace std;

void KWayMerge::ImportMessage()
{
	int i;
	int j;
	freopen("F:\\Practice\\2018.12.1 Blog\\ConsoleApplication1\\ConsoleApplication1\\Data.txt", "r", stdin);
	for (i = 0;i < K;i++)
	{
		//初始化键值位置
		data_sector[i].key = 0;
		//导入数据
		for (j = 0;j < MAX_DATA_NUM;j++)
		{
			cin >> data_sector[i].data[j];
		}
	}
}

void KWayMerge::KWayMergeSort()
{
	//加载初始叶子数据
	int i;
	for (i = 0;i < K;i++)
	{
		LoadData(i);
	}
	//创建初始败者树
	CreateLoserTree();
	while (leaf_node[loser_tree[0]] != MAX_KEY)
	{
		//输出胜者信息
		cout << "   " << leaf_node[loser_tree[0]] << "   ";
		//导入下一个参赛者信息
		LoadData(loser_tree[0]);
		//调整胜者树
		AdjustLoserTree(loser_tree[0]);
	}
}

//更新叶子节点
void KWayMerge::LoadData(int leaf_pos)
{
	if (data_sector[leaf_pos].key < MAX_DATA_NUM)
	{
		leaf_node[leaf_pos] = data_sector[leaf_pos].data[data_sector[leaf_pos].key++];
	}
	else
	{
		leaf_node[leaf_pos] = MAX_KEY;
	}
}

void KWayMerge::InitKWayMerge()
{
	leaf_node = new int[K];
	loser_tree = new int[K];
}

void KWayMerge::AdjustLoserTree(int leaf_pos)
{
	//指向父节点
	//因为败者树为不含叶子节点的完全二叉树所以加上K
	int i = (leaf_pos + K) / 2;
	//自下而上调整败者树
	for (;i > 0;i /= 2)
	{
		if (leaf_node[leaf_pos] > leaf_node[loser_tree[i]])
		{
			int temp;
			temp = leaf_pos;
			leaf_pos = loser_tree[i];
			loser_tree[i] = temp;
		}
	}
	//最终胜者
	loser_tree[0] = leaf_pos;
}

void KWayMerge::CreateLoserTree()
{
	//初始化败者树键值
	int i;
	for (i = 0;i < K;i++)
	{
		loser_tree[i] = MIN_KEY;
	}
	//调整树成为败者树
	for (i = K - 1;i >= 0;i--)
	{
		AdjustLoserTree(i);
	}
}

Data.txt

1 2 5 8 77 79 89 91 92 93
1 2 5 9 76 88 89 91 92 93
1 2 5 8 23 24 25 55 92 93
1 2 5 8 49 55 66 88 92 93
1 2 5 8 77 79 89 91 92 100
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值