在内存中简单模拟外部排序的归并过程

和真正的外部排序不同的是所有排序数据无论是处理前还是处理后的都在内存中,另外外部排序沿归并树自底向上逐层归并,归并趟数可能大于一,并且每一层参与每一次归并的k路数据往往有多组,即每一趟可能有多次归并,而这个在内存中模拟归并过程的简单小程序只模拟某一趟的一次归并。
归并采用的数据结构就是数据结构教材中介绍的败者树,具体参见相关数据结构教材,这里就不赘述了。
C++代码:

#include <iostream>
#include <vector>

using namespace std;

template <typename T>
void adjust(vector<size_t>& loser_tree, vector<T> &key, size_t start, size_t fathest_leaf_num, size_t offset, vector<bool> &infinity)
{
	size_t cur = start + 1;
	size_t parent;
	if (cur <= fathest_leaf_num)
	{
		parent = (cur + offset) / 2;
	}
	else
	{
		parent = (cur - fathest_leaf_num + key.size() - 1) / 2;
	}

	--cur;
	while (parent > 0)
	{
		if (loser_tree[parent] == key.size() || infinity[loser_tree[parent]] == false)
		{
			if (loser_tree[parent] != key.size())
			{
				if (cur != key.size())
				{
					if (infinity[cur] == false && key[loser_tree[parent]] >= key[cur])
					{
						parent /= 2;
						continue;
					}
					size_t temp = cur;
					cur = loser_tree[parent];
					loser_tree[parent] = temp;
				}
			}
			else
			{
				if (cur != key.size())
				{
					size_t temp = cur;
					cur = loser_tree[parent];
					loser_tree[parent] = temp;
				}
			}
		}
		parent /= 2;
	}
	loser_tree[0] = cur;
}

template <typename T>
void exteranlSort(vector<vector<T>> &input, vector<T> &sort_result, size_t merge_paths)
{
	size_t k = 1;
	while (k << 1 <= merge_paths - 1)
	{
		k <<= 1;
	}
	size_t offset = (k << 1) - 1;
	size_t farthest_num = merge_paths - k;
	size_t fathest_leaf_num = 2 * farthest_num;

	vector<size_t> loser_tree(merge_paths);
	vector<T> key(merge_paths);
	for (size_t i = 0; i < loser_tree.size(); ++i)
	{
		loser_tree[i] = key.size();
	}

	vector<bool> infinity(key.size(), false);
	vector<size_t> ptr_pos(input.size(), 0);
	for (size_t i = 0; i < key.size(); ++i)
	{
		if (ptr_pos[i] != input[i].size())
		{
			key[i] = input[i][ptr_pos[i]];
			++ptr_pos[i];
		}
		else
		{
			infinity[i] = true;
		}
	}

	for (size_t i = 0; i < key.size(); ++i)
	{
		adjust(loser_tree, key, i, fathest_leaf_num, offset, infinity);
	}

	while (infinity[loser_tree[0]] == false)
	{
		sort_result.push_back(key[loser_tree[0]]);

		if (ptr_pos[loser_tree[0]] != input[loser_tree[0]].size())
		{
			key[loser_tree[0]] = input[loser_tree[0]][ptr_pos[loser_tree[0]]];
			++ptr_pos[loser_tree[0]];
		}
		else
		{
			infinity[loser_tree[0]] = true;
		}

		adjust(loser_tree, key, loser_tree[0], fathest_leaf_num, offset, infinity);
	}

}
int main()
{
	vector<vector<int>> input{ {1, 2, 3, 5, 7, 9}, {3, 4, 20}, {1, 6, 7, 23}, {2, 4, 12, 15} };
	vector<int> sort_result;
	exteranlSort(input, sort_result, 4);
	cout << "排序结果" << endl;
	for (const auto& run : sort_result)
	{
		cout << run << " ";
	}
	cout << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值