【问题标题】:C library function to perform sort执行排序的 C 库函数
【发布时间】:2010-12-19 18:26:27
【问题描述】:

C 标准库中是否有可用的库函数来进行排序?

【问题讨论】:

  • @Alexandru,SO 的全部意义在于成为所有任何技能水平的编程相关问题的地方。当人们使用您的查询时,您认为 Google 应该将他们引导到哪里?希望它出现在here的权力 - 当 SO 是该查询的顶级 Google 链接时,我们的工作就完成了。
  • 我的原始代码很懒惰,可能与您通过 Google 搜索找到的代码大不相同。然而,在所有社区输入之后,您就有了一个如何使用 qsort 的良好实现示例。
  • @paxdiablo:如果是这样的话,他们还不如简单地托管标准的 lib 文档——我怀疑这个问题会在规范参考之上添加任何内容,这里。对于一些复杂的情况,也许 - 但只是为了找到一个基本功能?
  • 即使是这样的问题也有助于 SO 的最终完整性,作为对卡住的编码人员有用的数据库。
  • 在很多情况下人们也不知道要搜索什么。如果您知道 c 有一个名为 qsort() 的排序函数,那么文档很容易访问,但是如果您不知道应该使用什么资源。

标签: c sorting


【解决方案1】:

qsort() 是您正在寻找的功能。您可以使用指向数据数组的指针、该数组中的元素数量、每个元素的大小和一个比较函数来调用它。

它发挥了它的魔力,您的数组就地排序。下面是一个例子:

#include <stdio.h>
#include <stdlib.h>
int comp (const void * elem1, const void * elem2) 
{
    int f = *((int*)elem1);
    int s = *((int*)elem2);
    if (f > s) return  1;
    if (f < s) return -1;
    return 0;
}
int main(int argc, char* argv[]) 
{
    int x[] = {4,5,2,3,1,0,9,8,6,7};

    qsort (x, sizeof(x)/sizeof(*x), sizeof(*x), comp);

    for (int i = 0 ; i < 10 ; i++)
        printf ("%d ", x[i]);

    return 0;
}

【讨论】:

  • 您真的应该使用 sizeof(*x) 以防您将来更改类型,但 +1 以提供样本。
  • 在一般情况下,尝试通过将整数相减来比较整数会导致溢出。最好从一开始就远离那个坏习惯。使用return (f &gt; s) - (f &lt; s);
  • 好的,根据大多数建议进行了更改。我在需要 size_t 时画了一条线,@ChrisL,因为我的数组从来没有变得那么大:-) 而且,@AndreyT,虽然这个技巧很聪明,但我更喜欢我的代码可读:-)
  • @paxdiablo:“hack”是一个成熟的成语。任何称职的程序员都会立即认识到这一点。它对可读性没有负面影响。
  • @JAamish ISO C99 标准 N1256,在“7.20.5.2 qsort 函数”第 4 点“如果两个元素比较相等,则它们在结果排序数组中的顺序未指定。”
【解决方案2】:

C/C++ 标准库&lt;stdlib.h&gt; 包含qsort 函数。

这不是世界上最好的快速排序实现,但它足够快而且非常 易于使用... qsort 的正式语法是:

qsort(<arrayname>,<size>,sizeof(<elementsize>),compare_function);

您唯一需要实现的是 compare_function,它包含两个 “const void”类型的参数,可以转换为适当的数据结构,然后 返回以下三个值之一:

  • 否定,如果 a 应该在 b 之前
  • 0,如果 a 等于 b
  • 肯定的,如果 a 应该在 b 之后

1.比较整数列表

只需将 a 和 b 转换为整数 如果x &lt; y,x-y 为负,x == y,x-y = 0,x &gt; y,x-y 为正 x-y 是一种捷径:) 将*x - *y 反转为*y - *x,用于按降序/倒序排序

int compare_function(const void *a,const void *b) {
int *x = (int *) a;
int *y = (int *) b;
return *x - *y;
}

2。比较字符串列表:

为了比较字符串,你需要 &lt;string.h&gt; 库中的 strcmp 函数。 strcmp 默认情况下会适当地返回 -ve,0,ve... 以相反的顺序排序,只需反转 strcmp 返回的符号

#include <string.h>
int compare_function(const void *a,const void *b) {
return (strcmp((char *)a,(char *)b));
}

3.比较浮点数

int compare_function(const void *a,const void *b) {
double *x = (double *) a;
double *y = (double *) b;
// return *x - *y; // this is WRONG...
if (*x < *y) return -1;
else if (*x > *y) return 1; return 0;
}

4.根据键比较记录

有时您需要对更复杂的东西进行排序,例如记录。这里是最简单的 使用qsort 库的方法。

typedef struct {
int key;
double value;
} the_record;

int compare_function(const void *a,const void *b) {
the_record *x = (the_record *) a;
the_record *y = (the_record *) b;
return x->key - y->key;
}

【讨论】:

  • 一个很好的答案,但是比较函数的返回值的解释是倒退的。此外,在某些示例中,您正在使用 x-y 技巧,这可能会给出错误的结果(并且比简单的比较不那么明显)。
  • 好吧,就我现在而言..这适用于每场比赛;)
  • 如果 x 和 y 之间的差大于最大可表示的 int,则 x-y 技巧不起作用。所以比较两个正数是可以的,但是比较会失败,例如INT_MAX和-10。赞成,因为我喜欢所有分类不同类型的例子。
  • 以及整数比较器和键比较器函数中的溢出问题,字符串比较函数不正确。在对int 的数组进行排序时,传递给比较器的值都是int * 伪装成void *。因此,在对char * 的数组进行排序时,传递给比较器的值都是char ** 伪装成void *。因此,正确的代码需要是:int compare_function(const void *a,const void *b) { return (strcmp(*(char **)a, *(char **)b)); }.
  • 对于抗溢出的整数比较,考虑if (x &gt; y) return +1; else if (x &lt; y) return -1; else return 0;,或者如果你想要一个简单的表达式,那么return (x &gt; y) - (x &lt; y);。这总是在 C 级别评估两个比较,但优化器可能能够避免这种情况。减法不适用于无符号值。第一个版本在您处理一系列比较时效果很好 - 首先比较结构的 2 个整数成员,如果它们相等,然后是两个双精度数,然后是两个字符串,等等。有不止一种方法可以做到,在 C 和 Perl 中。
【解决方案3】:

当然:qsort() 是一种排序的实现(不一定是它的名字所暗示的快速排序)。

试试 man 3 qsort 或阅读http://linux.die.net/man/3/qsort

【讨论】:

  • qsort 不必使用快速排序来实现。
【解决方案4】:

虽然不完全在标准库中,https://github.com/swenson/sort 只有两个头文件,您可以包含这些头文件来访问各种令人难以置信的快速排序路由,如下所示:

#define SORT_NAME int64
#define SORT_TYPE int64_t
#define SORT_CMP(x, y) ((x) - (y))
#include “排序.h”
/* 您现在可以访问 int64_quick_sort、int64_tim_sort 等,例如 */
int64_quick_sort(arr, 128); /* 假设你有一些 int *arr 或 int arr[128]; */

这应该至少比标准库qsort 快两倍,因为它不使用函数指针,并且有许多其他排序算法可供选择。

它在 C89 中,所以基本上可以在每个 C 编译器中工作。

【讨论】:

    【解决方案5】:

    在 stdlib.h 中尝试qsort

    【讨论】:

      【解决方案6】:

      &lt;stdlib.h&gt; 中使用qsort()

      @paxdiablo qsort() 函数符合 ISO/IEC 9899:1990 (``ISO C90'')。

      【讨论】:

        【解决方案7】:

        我认为您正在寻找qsort
        qsort 函数是在stdlib.h 中的C/C++ 中找到的快速排序算法的实现。

        下面是调用qsort函数的语法:

        void qsort(void *base, size_t nmemb, size_t size,int (*compar)(const void *, const void *));
        

        参数列表:

        base:指向数组第一个元素或基地址的指针
        nmemb:数组中的元素数
        size:每个元素的字节大小
        compar:比较两个元素的函数元素

        这是一个使用qsort 对数组进行排序的代码示例:

        #include <stdio.h>
        #include <stdlib.h>
        
        int arr[] = { 33, 12, 6, 2, 76 };
        
        // compare function, compares two elements
        int compare (const void * num1, const void * num2) {
           if(*(int*)num1 > *(int*)num2)
            return 1;
           else
            return -1;
        }
        
        int main () {
           int i;
        
           printf("Before sorting the array: \n");
           for( i = 0 ; i < 5; i++ ) {
              printf("%d ", arr[i]);
           }
           // calling qsort
           qsort(arr, 5, sizeof(int), compare);
        
           printf("\nAfter sorting the array: \n");
           for( i = 0 ; i < 5; i++ ) {   
              printf("%d ", arr[i]);
           }
          
           return 0;
        }
        

        您可以在 Linux/Mac 终端输入man 3 qsort 以获取有关qsort 的详细信息。
        Link to qsort man page

        【讨论】:

          【解决方案8】:

          stdlib.h 中有几个可用的 C 排序函数。您可以在 unix 机器上执行 man 3 qsort 以获取它们的列表,但它们包括:

          • 堆排序
          • 快速排序
          • 合并排序

          【讨论】:

          • 堆排序和合并排序不在标准中。
          • 快速排序也不是。该标准没有规定使用哪种算法。
          猜你喜欢
          • 2021-04-29
          • 2022-01-22
          • 2016-03-02
          • 1970-01-01
          • 1970-01-01
          • 2010-12-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多