【问题标题】:C: sorting 2d arrays row by row using qsortC:使用 qsort 逐行排序二维数组
【发布时间】:2017-12-06 12:21:50
【问题描述】:

所以,我在这里想要实现的是在 2d 数组中使用 qsort 的 C 实现,我只希望根据其第一个元素对行进行排序,例如:

        int arr[3][2]={{65,1},
                       {45,2},
                       {66,3}}

我希望输出是:

        int arr[3][2]={{45,2},
                       {65,1},
                       {66,3}}

有没有办法在不自己实现快速排序的情况下做到这一点?如果有,怎么做?

编辑

这是我的代码的样子:

int f(int a, int b)
{
return a-b;
}

qsort(arr[0],3,sizeof(int),f);

【问题讨论】:

  • 你必须表现出你的努力。
  • 使用 stdlib.h 中的qsort()?
  • 对不起,我说的不够清楚,我觉得现在可以理解了...
  • 您确实提供了正确数量的元素:3。您没有提供正确的元素大小:sizeof (int)。当您想要对数组进行排序时,您必须提供这些数组的大小:sizeof (int[2])。我没有检查(也不记得)这是否是正确的语法,但2 * sizeof (int) 也应该这样做。顺便提一句。您的 f 无法对(子)数组进行排序。有什么理由将arr[0] 作为第一个参数(而不是arr)?不过,我想这应该没什么区别......
  • 好吧,我只希望它比较第一个元素,所以我只给它 arr[0],但现在让我试试

标签: c arrays quicksort qsort


【解决方案1】:

您不是在对整数进行排序,而是在对大小恰好是多个整数的“事物”进行排序。

所以,不要对qsort() 撒谎你的元素大小:

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

static int cmprow(const void *a, const void *b)
{
    const int * const ia = a, * const ib = b;
    return ia[0] < ib[0] ? -1 : ia[0] > ib[0];
}

int main(void) {
    int arr[3][2]={{65,1},
                   {45,2},
                   {66,3}};

    qsort(arr, sizeof arr / sizeof *arr, sizeof *arr, cmprow);
    for (size_t i = 0; i < sizeof arr / sizeof *arr; ++i)
    {
        for (size_t j = 0; j < sizeof *arr / sizeof **arr; ++j)
            printf("%d ", arr[i][j]);
        putchar('\n');
    }
    return 0;
}

打印出来:

45 2 
65 1 
66 3 

【讨论】:

    【解决方案2】:

    问题来了:

    qsort(arr[0],3,sizeof(int),f);
    

    此函数将size_t 作为第二个参数。你已经通过了 3。这不是大小,而是数组 arr 中元素的数量。粗略地说,你需要像3*sizeof(int) 这样的东西。或者更好sizeof(arr) / sizeof *arr。 所以,把它改成

    qsort(arr, sizeof(arr) / sizeof *arr, sizeof(int), sizeof *arr, comparator);
    

    与:

    int comparator(const void *p, const void *q)
    {
        // Get the values at given addresses
        int l = *(const int *)p;
        int r = *(const int *)q;
    
        // both odd, put the greater of two first.
        if ((l&1) && (r&1))
            return (r-l);
    
        // both even, put the smaller of two first
        if ( !(l&1) && !(r&1) )
            return (l-r);
    
        // l is even, put r first
        if (!(l&1))
            return 1;
    
        // l is odd, put l first
        return -1;
    }
    

    【讨论】:

      最近更新 更多