如何使用C++有效地合并排序与向量
How to efficiently merge sort with vectors using C++
我通过使用向量作为函数在 c++ 中实现了合并排序 参数而不是索引(开始、结束(。但是,我很想 知道这样做是否有任何权衡,就速度而言 和空间复杂性
代码:
void mergeSort(std::vector<int> &array) {
if(array.size() == 1) return;
else {
const unsigned int len = array.size();
const int lo = floor((double)len/2);
const int hi = ceil((double)len/2);
std::vector<int> L(&array[0], &array[lo]);
std::vector<int> R(&array[lo], &array[len]);
mergeSort(L);
mergeSort(R);
merge(array, L, R);
}
return;
}
每次调用合并排序时创建新列表可能不是要走的路, 但这就是合并排序功能的工作方式。另外,快/慢是:
std::vector<int> L(&array[0], &array[lo]);
合并函数如下所示:
void merge(
std::vector<int> &array,
std::vector<int> &L,
std::vector<int> &R
) {
std::vector<int>::iterator a = array.begin();
std::vector<int>::iterator l = L.begin();
std::vector<int>::iterator r = R.begin();
while(l != L.end() && r != R.end()) {
if (*l <= *r) {
*a = *l;
l++;
}
else {
*a = *r;
r++;
}
a++;
}
while (l != L.end()) {
*a = *l;
a++;
l++;
}
while (r != R.end()) {
*a = *r;
a++;
r++;
}
return;
}
好吧,不需要在每次调用合并时创建新空间。std::vector<int> L(&array[0], &array[lo]);
实际上将创建空间来容纳lo
元素,并且还将执行lo
副本。
您永远不会使用超过O(n)
额外的空间来存储值。那么,为什么不分配一个足够大的缓冲区来容纳 预先复制整个向量,并使每个递归调用对数据的特定部分进行操作?这样,您就不必在每次调用时都创建新的向量。
另外,我还鼓励您使mergesort
在迭代器上工作,而不是仅在vector<int>
上运行。像下面这样的界面应该就足够了。
template < typename Iterator, typename Compare>
void mergesort(Iterator s, Iterator e, Compare cmp);
在Github上,你可以找到我不久前实现的mergesort版本。我想应该足够了。
合并排序唯一需要的额外内存是大小n
数组,用于合并算法任何步骤产生的两个排序vector
中的任何一个。显然,您的解决方案使用更多。在第一次合并时,它分配两个长度n/2
向量,然后它将是四个n/4
向量,以此类推,总共给出n * log(n)
。这比n
略多.
分配vector
的成本通常与其长度呈线性关系(如果复制vector
的元素可以在 O(1( 中完成(,但您应该记住,如果您不使用自定义分配器,则在堆上分配内存是昂贵的操作。分配内存可能会发出系统调用,系统调用可能会使用复杂的算法来查找连续的内存片段以满足您的要求。它甚至可能需要将已经分配的内存片段移动到其他地方。因此,如果您可以坚持只进行一次分配,那么多次分配内存确实没有意义。
- 计算排序向量的向量中唯一值的计数
- 查找两个排序向量中共有的元素
- 对的排序向量 (std::vector<pair<int, int>>) 按对的第一个元素搜索并更新第二个元素值
- 如何从C++的对的排序向量中获取有关给定值的相应对
- 对象接收堆栈溢出异常 c++ 的排序向量
- "x"的所有元素都存在于"y"(排序向量)中吗?
- 指向指针排序向量的指针向量的 C++ 向量
- 未排序向量上的lower_bound/upper_bound
- 智能指针的排序向量:神秘崩溃
- 按类型排序向量并按类型或派生类型搜索
- 如何在不使用标准算法的情况下在排序向量中添加 c 元素?
- C++排序向量<double>与在<Object>双成员变量上键控的向量
- 字符串指针的排序向量
- 具有前导数字的字符串的排序向量
- 保证重新排序向量
- 结构解释的C 排序向量
- 更新排序向量的一个条目
- 通过在排序向量上使用二叉搜索来定位未排序向量中的元素
- 排序向量上 std::find_if 和 std::bind2nd 的替代品
- 使用QuickSort算法以降序排序向量