合并排序中的堆栈溢出 < >我有作业分配,通过递归实现C++中的合并排序。我不太擅长递归,下面是我实现的代码,但它给出了一个stackoverflow错误。 请告诉我我做错了什么。编辑版本 #include<iostream> using namespace std; void divide(int A[], int n); void sort(); int main(){ int A[4]={2,3,0,5}; divide(A, 4); for(int i =0 ;i<4;i++) cout<<A[i]<<endl; getchar(); } void divide(int A[], int n){ if(n<=2 && n>=1){ for(int i=0; i<n; i++) if(A[i]>A[i+1]){ int temp=A[i]; A[i]= A[i+1]; A[i+1]=temp; } } else{ divide(A, n/2); divide(A,(n/2)+1 ); } } #包括 使用名称空间std; 无效分割(整数A[],整数n); 无效排序(); int main(){ int A[4]={2,3,0,5}; 除名(A,4); 对于(int i=0;i
调用以下代码合并排序中的堆栈溢出 < >我有作业分配,通过递归实现C++中的合并排序。我不太擅长递归,下面是我实现的代码,但它给出了一个stackoverflow错误。 请告诉我我做错了什么。编辑版本 #include<iostream> using namespace std; void divide(int A[], int n); void sort(); int main(){ int A[4]={2,3,0,5}; divide(A, 4); for(int i =0 ;i<4;i++) cout<<A[i]<<endl; getchar(); } void divide(int A[], int n){ if(n<=2 && n>=1){ for(int i=0; i<n; i++) if(A[i]>A[i+1]){ int temp=A[i]; A[i]= A[i+1]; A[i+1]=temp; } } else{ divide(A, n/2); divide(A,(n/2)+1 ); } } #包括 使用名称空间std; 无效分割(整数A[],整数n); 无效排序(); int main(){ int A[4]={2,3,0,5}; 除名(A,4); 对于(int i=0;i,c++,sorting,C++,Sorting,调用以下代码 divide(A, 1); 应该说明这个问题 void divide(int A[], int n){ if(n==2){ // first time n==1 so no, further calls are n==0 so also no. for(int i=0; i<2; i++) if(A[i]>A[i+1]){ int temp=A[i]; A[
divide(A, 1);
应该说明这个问题
void divide(int A[], int n){
if(n==2){ // first time n==1 so no, further calls are n==0 so also no.
for(int i=0; i<2; i++)
if(A[i]>A[i+1]){
int temp=A[i];
A[i]= A[i+1];
}
} else{
divide(A, n/2); // for both n==1 and n== 0 => n==0, calls divide(A, 0)
divide(A,(n/2)+1 ); // calls divide(A, 1) always
}
}
现在,在程序的else部分中,您需要将A拆分为多个部分、N/2个元素和其他元素
divide(A, n/2);
在我们的示例中,这给出了n/2=3/2=1
除法(A,1)
从第n/2个元素后面的元素开始
divide(A+(n/2), n-(n/2));
第一个元素位于[0],因此剩余的元素从[1]开始,包含n-(n/2)=3-(3/2)=3-1=2个元素
现在,第一个if
,看起来像冒泡排序,但由于它处理数组末尾以外的元素而失败
if(n<=2 && n>=1){
for(int i=0; i<n; i++)
if(A[i]>A[i+1]) {
if(n=1){
对于(inti=0;iA[i+1]){
A[i+1]超出了i=1和n=2的数组末尾,n=2=>2个元素位于地址A[0]和A[1],因此A[i+1]=A[2]不是长度为2的数组A的一部分
for(int i=0; i<n-1; i++)
for(int i=0;i您仍然缺少合并。合并将需要第二个临时数组,我将其称为T,并假设它是从main传递的:
void divide(int A[], int T[], int n){
if(n < 2)
return;
if(n==2){
// ... swap A[0], A[1] if needed (the existing code is ok)
return;
}
divide(A, T, n/2); // recursively divide "left" half
divide(A+(n/2), T+(n/2), n-(n/2)); // recursively divide "right" half
merge(A, T, n/2, n) // merge the two halves
}
void divide(int A[],int T[],int n){
if(n<2)
返回;
如果(n==2){
//…根据需要交换[0]和[1](现有代码正常)
返回;
}
除法(A,T,n/2);//递归地将“左”半除法
除法(A+(n/2),T+(n/2),n-(n/2));//递归地将“右”半除法
合并(A,T,n/2,n)//合并两半
}
假设分区0或1元素已经排序可能更简单。因此,将其作为停止条件就足够了
if (n<=2) {
// correct code for swapping 1 or 2 elements
} else
if (n < 2)
return;
if(n<2)
返回;
divide(A,3)
?以及随后的divide(A,1)
?或者divide(A,0)
换言之,您希望得到什么呢?好吧,简单地说-这个递归永远不会结束。在if子句中,我猜您正在尝试进行交换,甚至看起来是错误的。这看起来与合并排序不太像。整个“merge”缺少部分。加上交换部分错误,递归终止条件错误,除法部分也错误(对数组的左部分执行相同的操作两次,而完全不接触右部分)为了更好地理解这个问题,你也可以这样做:拿一副扑克牌,只拿一副牌,洗牌,然后试着用手对它进行合并排序。感谢它对这个输入起了作用:[2,8,2,4,4,4,9,0,11]但对这个[2,8,2,4,9,0,11]没有作用[1]如果(n=1){for(int i=0;iA[i+1]){int temp=a[i];a[i]=a[i+1];A[i+1]=temp;}else{divide(A,n/2);divide(A,(n/2)+1);}尽管这改进了< <代码> > <代码>循环,但它仍然是错误的!考虑n=1和n=2。另外,另一部分由于不同的原因是错误的,您总是调用A,而不是拆分范围。我应该如何拆分它?更新的答案,您需要学习如何使用A+X数组来理解这一点。
if (n < 2)
return;