和真正的外部排序不同的是所有排序数据无论是处理前还是处理后的都在内存中,另外外部排序沿归并树自底向上逐层归并,归并趟数可能大于一,并且每一层参与每一次归并的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;
}