使用迭代器进行合并排序中的一个缓冲区

One buffer in merge sort using iterators

本文关键字:缓冲区 一个 迭代器 排序 合并      更新时间:2023-10-16

我在迭代器上写了一个合并排序,但每次我在递归中创建一个新向量时。我需要重载MergeSort函数,我将在其中创建一个向量,并将在递归调用中使用它。

template<typename Compare>
void Merge(TeamIterator begin, TeamIterator middle, TeamIterator end,
Compare &compare, Players &current_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, &current_vector[current_vector_index]);
std::copy(right, right_bound, &current_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项。您的实现利用了这个想法,但将其拆分为大量向量,每个向量都处于递归下降的任何给定级别。正如我所读到的,您的问题是,您如何停止这种情况,而是对所有临时存储使用单个向量。

我不会验证您的MergeMergeSort算法是否有效。相反,我将告诉您如何通过提供一个提供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)。这将设置一个临时空间分配,然后通过所有递归调用推送该空间分配。

对于任何错别字,我们深表歉意,但希望您能理解。

相关文章: