我对c ++中的递归有一个非常普遍的问题。为了更好地理解,我使用以下合并排序示例来解释我的不确定性。
void mergesort (int* first, int* last)
{
int n = last - first;
if (n<=1)return;
int* middle = first + n/2;
mergesort (first, middle);
mergesort (middle, last);
merge (first,middle, last);
}
必须定义函数merge
。函数参数int* first,int* last
分别指向数组中第一个和最后一个元素的指针。假设数组的长度为10.让我们看看会发生什么:
int* middle = first + 5;
。 现在我的问题:我们正在调用mergesort(first, middle)
,一旦我们将单个“元素”中的第一个数组拆分,这个递归就会结束。但是mergesort(middle,last)
在mergesort(first,middle)
终止或同时执行后会执行吗?不知何故,它必须同时出现,否则我们不会将后半部分分成单个“元素”。与上次合并排序相同的问题。那么递归如何执行多个函数调用?
编辑我添加了完整的源代码以及输出:
//Mergesort.cpp
//
#include <iostream>
void merge (int* first, int* middle, int* last)
{
int n = last - first;
std::cout<<"merge part, n= " << n<<"\n";
std::cout<<"merge part, middle= " << *middle << "\n";
std::cout<<"merge part, last= "<<*last << "\n";
int* deck = new int[n];
int* left = first;
std::cout<<"merge part, left = first " << *left<< "\n";
int* right = middle;
std::cout << "merge part, right = middle " << *right << "\n";
for (int* d = deck; d!=deck+n;++d){
if (left == middle) *d = *right++;
else if (right==last ) *d=*left++;
else if (*left < *right) *d = *left++;
else *d = *right++;}
int *d = deck;
while (first != middle) *first++ = *d++;
while (middle != last) *middle++ = *d++;
delete[] deck;
}
void mergesort (int* first, int* last)
{
int n = last - first;
if (n <= 1) return;
std::cout << "n= " << n;
int* middle = first + n/2;
std::cout << "first = "<< *first << "middle = "<< *middle<<"\n";
mergesort (first, middle);
mergesort (middle, last);
merge (first, middle, last);
}
int main ()
{
int a[4]={6,2,1,3};
int* first = a;
int* last = a+4;
mergesort (first, last);
std::cout<< a[0]<< a[1]<< a[2]<< a[3]<<"\n";
return 0;
}
输出:
ThinkStation-S20:~/c++/test_files$ ./mergesort
n= 4first = 6middle = 1
n= 2first = 6middle = 2
merge part, n= 2
merge part, middle= 2
merge part, last= 1
merge part, left = first 6
merge part, right = middle 2
n= 2first = 1middle = 3
merge part, n= 2
merge part, middle= 3
merge part, last= 4197792
merge part, left = first 1
merge part, right = middle 3
merge part, n= 4
merge part, middle= 1
merge part, last= 4197792
merge part, left = first 2
merge part, right = middle 1
1236
答案 0 :(得分:2)
merge
的适当定义,这将很好地工作。我强烈建议您自己尝试该程序,用纸和笔模拟计算机。它不会花太长时间(诚实!)它应该解决你的疑虑。
与quicksort一样,mergesort可以(部分)并行执行。对mergesort的两个递归调用是相互独立的,因此执行可能会重叠。但是,如果没有相当多的额外工作,C ++就不会为你做到这一点。
这是用铅笔和纸做的一种方法,我认为比试图解释printf输出更容易理解。
main
。答案 1 :(得分:0)
同时没有任何事情发生,它有助于将每个连续的函数调用视为添加到堆栈。在函数结束时,它会弹出堆栈并继续。