在C中合并排序

时间:2015-01-28 09:58:53

标签: c algorithm mergesort

我是编程/ C的新手。 我将merge-sort算法理解为算法,但是当涉及到编程时,似乎我做错了。 有人可以帮忙吗?

感谢。

这是我的代码:

merge(int A[],int p,int q,int r);
part(int A[],int p,int r);

int main()
{
int A [6]={10,5,4,0,11,7}, n,y,z;

y=1; z=sizeof(A)/sizeof(int);

part(A,y,z);
for(n=0;n<z;n++)
printf("%d\n", A[n]);

    return 0;
}

part(int A[],int p,int r)
{
    if (p<r)
    {
        int q=(p+r)/2;
        part(A,p,q);
        part(A,q+1,r);
        merge(A,p,q,r);
    }
}

merge(int A[],int p,int q,int r)
{
    int n1=q-r+1,n2=r-q,L[n1+1],R[n2+1],i,j,k;
    L[n1+1]=100000;
    R[n2+1]=100000;
    for (i=0;i<n1;i++)
        L[i]=A[p-1+i];
    for (j=0;j<n2;j++)
        R[j]=A[q+j];
    i=0;j=0;
    for (k=0;k<r;k++)
        if(L[i]<=R[j])
    {
        A[k]=L[i];
        i++;
    }
    else
    {
        A[k]=R[j];
        j++;
    }
}

2 个答案:

答案 0 :(得分:2)

以下是您更正后的代码:

#include<stdio.h>
#include<limits.h>

void merge(int A[],int p,int q,int r);
void part(int A[],int p,int r);

int main()
{
int A [6]={10,5,4,0,11,7}, n,y,z;

y=0; z=6;

part(A,0,z-1); // Pass starting from 0 to Length - 1 of Array
for(n=0;n<z;n++)
printf("%d\n", A[n]);

    return 0;
}

void part(int A[],int p,int r)
{
    if (p<r)
    {
        int q=(p+r)/2;
        part(A,p,q);
        part(A,q+1,r);
        merge(A,p,q,r);
    }
}

void merge(int A[],int p,int q,int r)
{
    int n1=q-p+1,n2=r-q;
    int L[n1+1],R[n2+1],i,j,k;
    L[n1]=INT_MAX;
    R[n2]=INT_MAX;

    for (i=0;i<n1;i++)
        L[i]=A[p+i];

    for (j=0;j<n2;j++)
        R[j]=A[q+j+1];

    i=0;j=0;

    for (k=p;k<=r;k++)
    {
        if(L[i]<=R[j])
        {
            A[k]=L[i];
            i++;
        }
        else
        {
            A[k]=R[j];
            j++;
        }
    }
}

这些是错误的部分:

int n1=q-r+1,n2=r-q  // --> Your calculation of new indices was wrong

这些索引会超出数组的范围:

L[n1+1]=100000;
R[n2+1]=100000;

也可以使用100000中的INT_MAX等随机值代替limits.h中的 for (k=0;k<r;k++) // ->wrong 作为哨兵元素。

0

您应该从数组的左侧索引向右移动而不是从0 4 5 7 10 11 索引。

输出:

{{1}}

休息,你可以自己检查。

答案 1 :(得分:0)

使用零件参数0到数组大小的替代解决方案。我的旧C编译器不支持可变大小的数组,因此我使用_alloca()作为替代。其他替代方法是传递第二个数组以用作合并排序的临时数组,以及自上而下或自下而上合并排序。通过使用一对共同递归函数交替基于递归级别的合并方向,可以自上而下避免复制操作:顶级将是partAtoA(),它将调用partAtoB()(这将叫partAtoA(),...)。

#include <stddef.h>
#include <stdio.h>

void merge(int A[],int p,int q,int r);
void part(int A[],int p,int r);

int main()
{
int A[6]={10,5,4,0,11,7}, n,y,z;
    y=0;
    z=sizeof(A)/sizeof(int);
    part(A,y,z);
    for(n=0;n<z;n++)
        printf("%d\n", A[n]);
    return 0;
}

void part(int A[], int p, int r)
{
int q;
    if ((r - p) < 2)
        return;
    q=(p+r)/2;
    part(A,p,q);
    part(A,q,r);
    merge(A,p,q,r);
}

void merge(int A[],int p,int q,int r)
{
int n1=q-p, n2=r-q;
int i,j,k;
/* using _alloca for variable size arrays */
int * L = _alloca(n1*sizeof(int));
int * R = _alloca(n2*sizeof(int));
    for (i=0; i<n1; i++)
        L[i]=A[p+i];
    for (j=0; j<n2; j++)
        R[j]=A[q+j];
    i=0;j=0;
    for(k=p;k<r;k++)
        if(j>=n2 || i<n1 && L[i]<=R[j])
            A[k]=L[i++];
        else
            A[k]=R[j++];
}