【发布时间】:2017-07-07 14:49:29
【问题描述】:
我通过使用向量作为函数在 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而不是迭代器的权衡实际上只是您的算法不再是通用的。由于算法本身在内部使用迭代器,我很难找到优势。您真的必须测试和衡量自己才能知道是否有任何性能优势。 -
考虑将问题发布到codereview.stackexchange.com
-
这不太可能产生明显的性能差异,但执行
lo = len / 2; hi = len - lo;可以避免浮点数学运算。 -
保留一些长度 (l.size() + r.size());由于您采用了一体化方法,我认为使用原始数据会更快( l.data() ),然后使用 duff 设备和/或 omp for-loop 优化。如果你在某个循环中使用这个函数,那么考虑 do-while 更快
-
性能是主要目标吗?如果是这样,那么对于自上而下的合并排序,对工作向量进行一次分配,并使用相互递归来根据递归级别改变合并的方向。实现自下而上的合并排序会稍微快一些。输入参数是指向向量或数组的开始和结束的指针会更通用。