合并排序不给出正确的输出,c

时间:2017-05-24 08:20:50

标签: c algorithm sorting mergesort

我已经使用指针进行了合并排序代码,因为我希望一旦它运行并且输出错误,就会使代码动态化。可以使用动态全局数组来完成,如果是这样的话,怎么办呢?以下代码:

    #include<stdio.h>
void merge(int *a,int low,int mid,int high,int n){
    int l1=low,l2=mid+1,i;
    int b[n];

    for(i=low;l1<=mid&&l2<=high;i++){
        if((*(a+(l1 )))<(*(a+(l2 )))){
            b[i]=*(a+(l1 ));
            l1++;
        }
        else{
            b[i]=*(a+(l2 ));
            l2++;

        }
    }
    while(l1<=mid){
        b[i++]=(*(a+(l1 )));
        l1++;
    }
  while(l2<=mid){
        b[i++]=(*(a+(l1 )));
        l2++;
    }
    for(i=low;i<=high;i++){
       ( *(a+(l1 )))=b[i];
    }
}
void sort(int *a,int low,int high,int n){
    if(low<high){
        int mid=(low+high)/2;
        sort(a,low,mid,n);
        sort(a,mid+1,high,n);
        merge(a,low,mid,high,n);

    }
    else {
        return;

    }
}
int main(void){
        int a[3]={5,2,1};

    sort(&a[0],0,2,3);
    for(int i=0;i<3;i++){
        printf("%d ",a[i]);
    }
}   

或者如果有人有任何想法使用动态大小的数组来制作这个程序我就可以了。我也为此编写了一个没有指针的代码,但它使用全局变量,因此使用了固定数组。我在下面发布它作为参考,我所做的就是在该代码中实现指针。

#include<stdio.h>
int a[6]={5,2,1,6,3,4};
int b[6];
void merge(int low,int mid,int high){
    int l1=low,l2=mid+1,i;
    for(i=low;l1<=mid&&l2<=high;i++){
        if(a[l1]<a[l2]){
            b[i]=a[l1++];
        }
        else{
            b[i]=a[l2++];

        }
    }
    while(l1<=mid){
        b[i++]=a[l1++];
    }
  while(l2<=mid){
        b[i++]=a[l2++];
    }
    for(i=low;i<=high;i++){
        a[i]=b[i];
    }
}
void sort(int low,int high){
    if(low<high){
        int mid=(low+high)/2;
        sort(low,mid);
        sort(mid+1,high);
        merge(low,mid,high);

    }
    else {
        return;

    }
}
int main(void){
    sort(0,5);
    for(int i=0;i<=6;i++){
        printf("%d ",a[i]);
    }
}    

将代码更改为以下代码以便更好地调试:我发现b没有被赋值,也不是:

    #include<stdio.h>
#include<stdlib.h>
void merge(int *a,int low,int mid,int high,int n){
    int l1=low,l2=mid+1,i;
    int *b=malloc(n );

    for(i=low;l1<=mid&&l2<=high;i++){
        if((*(a+(l1 )))<(*(a+(l2 )))){
            (*(b+(i )))=*(a+(l1 ));
        debug  pritnf("%d\n",(*(b+(i ))));
            l1++;
        }
        else{
            (*(b+(i )))=*(a+(l2 ));

            l2++;

        }
    }
    while(l1<=mid){
        (*(b+(i )))=(*(a+(l1 )));
        l1++;
        i++;
    }
  while(l2<=mid){
        (*(b+(i )))=(*(a+(l1 )));
        l2++;
        i++;
    }
    for(i=low;i<=high;i++){
       ( *(a+(l1 )))=(*(b+(i )));
    }
}
void sort(int *a,int low,int high,int n){
    if(low<high){
        int mid=(low+high)/2;
        sort(a,low,mid,n);
        sort(a,mid+1,high,n);
        merge(a,low,mid,high,n);

    }
    else {
        return;

    }
}
int main(void){
        int a[3]={5,2,1};

    sort(&a[0],0,2,3);
    for(int i=0;i<3;i++){
        printf("%d ",a[i]);
    }
}      

在这开始工作之后它完全有效,我尝试了动态数组,并没有为我提供正确的输出,因为在中间是零,而最大的数字不在那里。代码如下:

#include<stdio.h>
#include<stdlib.h>

void merge(int *a,int low,int mid,int high,int n){
    int l1=low,l2=mid+1,i;
    int *b=malloc((n-1) *sizeof(int));

    for(i=low;l1<=mid&&l2<=high;i++){
        if((*(a+(l1 )))<=(*(a+(l2 )))){
            (*(b+(i )))=*(a+(l1 ));
            l1++;
        }
        else{
            (*(b+(i )))=*(a+(l2 ));

            l2++;

        }
    }
    while(l1<=mid){
        (*(b+(i )))=(*(a+(l1 )));
        l1++;
        i++;
    }
  while(l2<=mid){
        (*(b+(i )))=(*(a+(l1 )));
        l2++;
        i++;
    }
    for(i=low;i<=high;i++){
       ( *(a+(i )))=(*(b+(i )));
    }
}
void sort(int *a,int low,int high,int n){
    if(low<high){
        int mid=(low+high)/2;
        sort(a,low,mid,n);
        sort(a,mid+1,high,n);
        merge(a,low,mid,high,n);

    }
    else {
        return;

    }
}
int main(void){
    int n;
    scanf("%d",&n);
        int a[n];


    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }

    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }

    sort(&a[0],0,n-1,n);
    for(int i=0;i<n;i++){
        printf("%d ",a[i]);
    }
}   

2 个答案:

答案 0 :(得分:0)

只需查看代码,就需要修复复制循环:

    for(i=low;i<=high;i++){
       ( *(a+(i )))=(*(b+(i )));   /* a+(i) not a+(l1) */
    }

代码实际上不是基于指针的,它只是使用[i]的替代语法,即*(a + i)。对于基于指针的合并排序版本,低,中,高应该是指针,而不是索引。

答案 1 :(得分:-1)

在你的merge()函数中,你写了

while(l1<mid){
    b[i]=*(a+(l1*sizeof(int)));
    l1++;
}
while(l2<=high){
    b[i]=*(a+(l2*sizeof(int)));
    l2++;
}

我认为你应该在这两个循环中添加i++;

编辑:(问题编辑后)

这一次你写了这个:

for(i=low;l1<mid && l2<=high;i++){
    if(*(a+(l1*sizeof(int)))<*(a+(l2*sizeof(int)))){
        b[i]=*(a+(l1*sizeof(int)));
        l1++;
        i++; // you added this line
    }
    else{

            b[i]=*(a+(l2*sizeof(int)));
            l2++;
            i++; // you added this line

    }
}

但是你不需要在那里添加那些行 - 这个增量已经由for循环完成了。通过添加这些语句,您实际上在循环的每个步骤中递增i两次 - 您不需要这样做。

然后,merge()中的循环将变为如下:

for(i=low;l1<mid && l2<=high;i++){
    if(*(a+(l1*sizeof(int)))<*(a+(l2*sizeof(int)))){
        b[i]=*(a+(l1*sizeof(int)));
        l1++;
        //i++; // unnecessary
    }
    else{

            b[i]=*(a+(l2*sizeof(int)));
            l2++;
            //i++; // unnecessary

    }
}
while(l1<mid){
    b[i]=*(a+(l1*sizeof(int)));
    l1++;
    i++; // add this line
}
while(l2<=high){
    b[i]=*(a+(l2*sizeof(int)));
    l2++;
    i++; // add this line
}