以快速排序为例,下面列出了递归和非递归方法。
我认为这两种方法实际上都实现了相同的算法,因为stack
用于模拟非递归方法中的递归过程。
但是,我通过递归方法得到了AC,但是在85%的测试用例通过后,时间限制超过了非递归方法。
那么,我的非递归方法有什么问题,或者两种方法之间存在时间复杂度差异?
谢谢!
// 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);
}
乍一看,你在循环的底部:
ranges.push(pair<int, int>(0, left - 1));
ranges.push(pair<int, int>(left + 1, r.second));
对我来说应该是
ranges.push(pair<int, int>(r.first, left - 1));
ranges.push(pair<int, int>(left + 1, r.second));