为什么我的mergesort程序会触发分段错误?

时间:2015-03-14 12:43:12

标签: c algorithm sorting data-structures

#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

1 个答案:

答案 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太小而且可以触发未定义行为,例如分段错误和提前终止。

为了解决这个问题,引入了另一个索引jint 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;
}