#include<stdio.h>
void merge(int a[],int left[],int l,int right[],int r){
int i=0,j=0,k=0;
while(i<l&&j<r){
if(left[i]<=right[j]){
a[k]=left[i];
k++;
i++;
}
else{
a[k]=right[j];
k++;
j++;
}
}
while(i<l){
a[k]=left[i];
k++;
i++;
}
while(j<r){
a[k]=right[j];
k++;
j++;
}
}
void mergesort(int a[],int s,int n){
int i;
int mid=(s+n)/2;
int left[mid],right[n-mid];
if(n<2) return;
else{
for(i=s;i<mid;i++){
left[i]=a[i];
}
for(i=mid;i<n;i++){
right[i]=a[i];
}
mergesort(left,s,mid);
mergesort(right,n-mid,n);
merge(a,left,mid,right,n-mid);
}
}
int main(int argv,char*argc){
int a[]={9,8,7,5,1,2,4,3,6},i;
printf("sorting....");
mergesort(a,0,9);
for(i=0;i<10;i++){
printf("\n");
printf("%d",a[i]);
}
return 1;
}
程序终止之前givin输出...请帮助.. 逻辑取自mycodeschool.org
答案 0 :(得分:0)
正如评论中所述,for(i=mid+1;i<n;i++){ right[i]=a[i]; }
最多可达i=n-1
,但right
被声明为int mid=(s+n)/2; int left[mid],right[n-mid];
:right
太小而且可以触发未定义行为,例如分段错误和提前终止。
为了解决这个问题,引入了另一个索引j
:int j=0;for(i=mid+1;i<n;i++){ right[j]=a[i]; j++; }
,对数组left
也是如此。对mergesort()
的调用必须相应更改:
mergesort(left,mid);
mergesort(right,n-mid);
第二个参数s
已被删除。它可以在以后重新引入,以避免不必要的副本并减少内存占用。
额外的小问题是int a[]={9,8,7,5,1,2,4,3,6},i;...for(i=0;i<10;i++)
:a
有9个项目,for循环尝试访问第十个项目a[9]
。
这是一个提供预期输出的更正代码。用gcc main.c -o main
#include<stdio.h>
void merge(int a[],int left[],int l,int right[],int r){
int i=0,j=0,k=0;
while(i<l&&j<r){
if(left[i]<=right[j]){
a[k]=left[i];
k++;
i++;
}
else{
a[k]=right[j];
k++;
j++;
}
}
while(i<l){
a[k]=left[i];
k++;
i++;
}
while(j<r){
a[k]=right[j];
k++;
j++;
}
}
void mergesort(int a[],int n){
int i;
int mid=(n)/2;
int left[mid],right[n-mid];
if(n<2) return;
else{
int j=0;
for(i=0;i<mid;i++){
left[j]=a[i];
j++;
}
j=0;
for(i=mid;i<n;i++){
right[j]=a[i];
j++;
}
mergesort(left,mid);
mergesort(right,n-mid);
merge(a,left,mid,right,n-mid);
}
}
int main(int argv,char*argc){
int a[]={9,8,7,5,1,2,4,3,6},i;
printf("sorting....\n");
mergesort(a,9);
for(i=0;i<9;i++){
printf("%d\n",a[i]);
}
return 0;
}