在C

时间:2018-04-09 14:37:21

标签: c struct heap quicksort qsort

我必须编写一个使用qsort函数对矢量进行排序的程序 笛卡尔平面中的点数。每个点由一对形成 坐标(x,y)。 点必须按升x轴排序。使用相同的x轴, y轴按降序排列。

这是一个示例输入:

5 (Struct numbers)
2 5
12 2
2 7
3 4
2 2

输出:

2 7
2 5
2 2
3 4
12 2

现在,这是我的代码:

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

typedef struct x_y
{
    int x;
    int y;
}coordinates;
typedef coordinates *coordinatesList;

int compare(const void *a, const void *b)
{
    coordinates *a1 = (coordinates *)a;
    coordinates *b1 = (coordinates *)b;
    if (a1->x > b1->x)
        return 1;
    else if (a1->x < b1->x)
        return (-1);
    else if (a1->x == b1->x)
    {
        if (a1->y < b1->y)
            return 1;
        else if (a1->y > b1->y)
            return (-1);
        else
            return 0;
    }
}

int main()
{
    int n, i;
    scanf("%d", &n);
    coordinatesList *A = (coordinatesList*)malloc(n * sizeof(coordinates));
    for (i = 0; i < n; i++)
    {
        A[i] = (coordinatesList)malloc(sizeof(coordinates));
        scanf("%d%d", &A[i]->x, &A[i]->y);
    }
    qsort(A, n, sizeof(coordinates*), compare);
    for (i = 0; i < n; i++)
        printf("%d %d\n", A[i]->x, A[i]->y);
    return 0;
}

他的错误输出:

2 7
3 4
2 2
2 5
12 2

如果我尝试按元素分隔结构:

int compare(const void *a, const void *b)
{
    coordinates *a1 = (coordinates *)a;
    coordinates *b1 = (coordinates *)b;
    int a_x = a1->x;
    int a_y = a1->y;
    int b_x = b1->x;
    int b_y = b1->y;
    if (a_x > b_x)
        return 1;
    else if (a_x < b_x)
        return (-1);
    else if (a_x == b_x)
    {
        if (a_y < b_y)
            return 1;
        else if (a_y > b_y)
            return (-1);
        else
            return 0;
    }
}

...给了我一个不同的错误输出:

2 2
12 2
2 7
3 4
2 5

2 个答案:

答案 0 :(得分:2)

compare函数获取指向要排序的元素的指针,因此它获取指向坐标指针的指针。正确的开始是:

int compare(const void *a, const void *b)
{
    const coordinates *a1 = *(const coordinates **)a;
    const coordinates *b1 = *(const coordinates **)b;

我添加了const因为你不应该抛弃常数,即使它在这里并不重要。如果你在编辑中使用了警告,你会注意到。

您还应该在sizeof(coordinates)的调用中使用qsort,而不是sizeof(coordinates*),因为否则排序功能无法知道您的元素有多大,但这两个可能这里有相同的价值。

答案 1 :(得分:2)

对于根据C标准的初学者,没有参数的函数main应声明为

int main( void )

在此声明中

coordinatesList *A = (coordinatesList*)malloc(n * sizeof(coordinates));

您必须使用表达式sizeof( coordinatesList )而不是表达式sizeof( coordinates )

在函数compare中你必须写

int compare(const void *a, const void *b)
{
    const coordinatesList a1 = *( const coordinatesList *)a;
    const coordinatesList b1 = *( const coordinatesList *)b;
    //...

这是一个示范程序

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

typedef struct x_y
{
    int x;
    int y;
} coordinates;

typedef coordinates *coordinatesList;

int compare( const void *a, const void *b )
{
    const coordinatesList a1 = *( const coordinatesList * )a;
    const coordinatesList b1 = *( const coordinatesList * )b;

    if ( a1->x < b1->x )
    {
        return -1;
    }
    else if ( b1->x < a1->x )
    {
        return 1;
    }
    else
    {
        if ( a1->y < b1-> y )
        {
            return 1;
        }
        else if ( b1->y < a1->y )
        {
            return -1; 
        }
        else
        {
            return 0;
        }
    }
}

int main(void) 
{
    const size_t N = 5;

    coordinatesList *A = malloc( N * sizeof( coordinatesList ) );

    for ( size_t i = 0; i < N; i++ )
    {
        A[i] = malloc( sizeof( coordinates ) );
    }

    A[0]->x = 2;  A[0]->y = 5;
    A[1]->x = 12; A[1]->y = 2;
    A[2]->x = 2;  A[2]->y = 7;
    A[3]->x = 3;  A[3]->y = 4;
    A[4]->x = 2;  A[4]->y = 2;

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d\t%d\n", A[i]->x, A[i]->y );
    }
    putchar( '\n' );

    qsort( A, N, sizeof( coordinatesList ), compare );

    for ( size_t i = 0; i < N; i++ )
    {
        printf( "%d\t%d\n", A[i]->x, A[i]->y );
    }
    putchar( '\n' );

    return 0;
}

它的输出是

2   5
12  2
2   7
3   4
2   2

2   7
2   5
2   2
3   4
12  2