使用迭代器进行合并排序中的一个缓冲区
One buffer in merge sort using iterators
我在迭代器上写了一个合并排序,但每次我在递归中创建一个新向量时。我需要重载MergeSort
函数,我将在其中创建一个向量,并将在递归调用中使用它。
template<typename Compare>
void Merge(TeamIterator begin, TeamIterator middle, TeamIterator end,
Compare &compare, Players ¤t_vector) {
TeamIterator left = begin;
TeamIterator left_bound = middle;
TeamIterator right = middle;
TeamIterator right_bound = end;
size_t current_vector_index = 0;
while (left != left_bound && right != right_bound) {
if (compare(*right, *left)) {
current_vector[current_vector_index] = *right;
current_vector_index = current_vector_index + 1;
right = right + 1;
} else {
current_vector[current_vector_index] = *left;
current_vector_index = current_vector_index + 1;
left = left + 1;
}
}
std::copy(left, left_bound, ¤t_vector[current_vector_index]);
std::copy(right, right_bound, ¤t_vector[current_vector_index]);
std::copy(current_vector.begin(), current_vector.end(), begin);
}
template<typename Compare>
void MergeSort(TeamIterator begin, TeamIterator end, Compare &compare) {
auto size = std::distance(begin, end);
if (size < 2) {
return;
}
TeamIterator middle = std::next(begin, size / 2);
MergeSort(begin, middle, compare);
MergeSort(middle, end, compare);
Players current_vector(size);
Merge(begin, middle, end, compare, current_vector);
}
我该怎么做?
您似乎明白,除了某些就地合并实现的复杂工作之外,传统的合并排序需要额外的N
空间来N
项。您的实现利用了这个想法,但将其拆分为大量向量,每个向量都处于递归下降的任何给定级别。正如我所读到的,您的问题是,您如何停止这种情况,而是对所有临时存储使用单个向量。
我不会验证您的Merge
或MergeSort
算法是否有效。相反,我将告诉您如何通过提供一个提供N
空间的中间函数来设置您所寻求的内容,然后将其向下传播到需要三个迭代器的内部MergeSort
;不是两个。第三个是在当前下降时临时存储合并的目标位置
首先是主前端,在参数方面看起来与您的相同。
template<typename Compare>
void MergeSort(TeamIterator begin, TeamIterator end, Compare &compare)
{
auto size = std::distance(begin, end);
if (size < 2) {
return;
Player tmp(size); // the one-time temp-space allocation of N items.
MergeSort(begin, end, tmp.begin(), compare);
}
请注意,这是调用一个需要三个迭代器的MergeSort
重载,而不是两个。 这将实现为:
template<typename Compare>
void MergeSort(TeamIterator begin, TeamIterator end, TeamIterator tmp, Compare &compare)
{
auto size = std::distance(begin, end);
if (size < 2) {
return;
TeamIterator middle = std::next(begin, size / 2);
MergeSort(begin, middle, tmp, compare);
MergeSort(middle, end, std::next(tmp, size / 2), compare);
Merge(begin, middle, end, tmp, compare);
}
最后,这是调用一个需要四个迭代器的Merge
,而不是三个:
template<typename Compare>
void Merge(TeamIterator begin, TeamIterator middle, TeamIterator end,
TeamIterator tmp, Compare &compare) {
TeamIterator left = begin;
TeamIterator right = middle;
TeamIterator dst = tmp;
while (left != middle && right != end)
{
if (compare(*right, *left))
*dst++ = *right++;
else
*dst++ = *left++;
}
// account for early termination from right-side finish.
if (left != middle)
{
std::copy(left, middle, dst);
std::advance(dst, std::distance(left, middle));
}
// copy move everything we sorted back into the partition
std::copy(tmp, dst, begin);
}
从那里,您的调用方将执行它现在正在执行的操作:调用MergeSort(begin, end, compare)
。这将设置一个临时空间分配,然后通过所有递归调用推送该空间分配。
对于任何错别字,我们深表歉意,但希望您能理解。
相关文章:
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 绘制一个对象,比较模具缓冲区的两个不同值
- 如果我向一个12字节的缓冲区写入的字节数少于12,会发生什么情况
- 使用迭代器进行合并排序中的一个缓冲区
- 创建一个结构的关联数组,以创建一个缓冲区,供键快速访问
- 创建一个简单的前向迭代器,该迭代器在循环缓冲区的"end"处自动换行
- 我该如何循环遍历我的数组(缓冲区——包含一个文本文件),并将其打印成30字节的块
- 定义一个带有缓冲区的函数作为卤化物中的边界框参数
- 我正在编写一个简单的客户端套接字应用程序,但在连接后服务器收到一个空缓冲区
- window.display() 单独在显示的最后一个缓冲区和当前缓冲区之间切换
- 两个C++库如何共享一个静态缓冲区?
- 缓冲区用不需要的数据填充 char 数组中的最后一个空格
- 是否可以在同一设备缓冲区上一个接一个地调用 OpenCL 内核?
- 我可以做一个循环,直到“std::cin”在输入缓冲区中看到“”字符
- 堆缓冲区溢出随机发生。对于一个简单的代码?(我是C++新手)
- OpenGL-缓冲区更新下一个渲染对象
- 在缓冲区中以十六进制格式插入一个值
- 一个缓冲区如何用新行C++输出
- 一个粒子太多:GL_INVALID_VALUE生成错误。<start> 不满足着色器存储缓冲区的最低对齐要求
- CUDA中一个简单Z缓冲区的实现