【发布时间】:2018-05-31 09:21:06
【问题描述】:
以快速排序为例,下面列出了递归和非递归的方法。
我认为这两种方法实际上实现了相同的算法,因为stack用于模拟非递归方法中的递归过程。
但是,在 85% 的测试用例通过后,我使用递归方法获得了 AC,但 Time Limit Exceeded 使用非递归方法。
那么,我的非递归方法有什么问题,或者两种方法之间存在时间复杂度差异?
谢谢!
// non-recursion
void sortIntegers(vector<int> &A) {
if (A.empty()) {
return;
}
stack<pair<int, int>> ranges;
ranges.push(pair<int, int>(0, A.size() - 1));
while (!ranges.empty()) {
pair<int, int> r = ranges.top();
ranges.pop();
int mid = A[r.second],
left = r.first,
right = r.second - 1;
if (r.first >= r.second) {
continue;
}
while (left < right) {
while (A[left] < mid && left < right) {
left++;
}
while (A[right] >= mid && left < right) {
right--;
}
swap(A[left], A[right]);
}
if (A[left] < A[r.second]) {
left++;
} else {
swap(A[left], A[r.second]);
}
ranges.push(pair<int, int>(0, left - 1));
ranges.push(pair<int, int>(left + 1, r.second));
}
// recursion
void sortIntegers(vector<int> &A) {
quick(A, 0, A.size() - 1);
}
void quick(vector<int> & A, int start, int end) {
if (start >= end) {
return;
}
int mid = A[end], //5
left = start, // 0
right = end - 1; //3
while (left < right) {
while (A[left] < mid && left < right) {
left++;
}
while (A[right] >= mid && left < right) {
right--;
}
swap(A[left], A[right]);
}
if (A[left] >= A[end]) {
swap(A[left], A[end]);
}else {
left++;
}
quick(A, start, left - 1);
quick(A, left + 1, end);
}
【问题讨论】:
-
函数调用被大量使用,因此很可能被编译器优化得很好。例如,参数可能会在寄存器中传递,而不是像显式堆栈那样存储到内存中。
-
您的
sortIntegers函数在此行访问越界项目:int mid = A[r.second]。请see this version of your function usingvector::at()。因此,如果您的函数引入了未定义的行为,您将无法确定某事是快还是慢。先修复你的非递归函数,然后重新运行你的结果。
标签: c++ algorithm sorting recursion quicksort