c语言 -- 快速排序函数qsort

快速排序函数

函数原型

#include<stdlib.h>

void qsort(void*, size_t, size_t, int ( * )(const void * ,  const void *  ))

1. 第一个参数为待排序数组首地址。

可直接输入待排序数组名,或是指向数组的指针。

2. 第二个参数为数组长度。

size_t是标准C库中定义的,应为unsigned int,在64位系统中为 long unsigned int。
可以直接输入待排序的数组的长度。

3. 第三个参数为数组元素所占字节。

可直接用sizeof(a[0])计算字数组单个元素的节数。

4. 第四个参数为所调用函数的指针,函数名即是函数的指针,可直接写函数名,调用函数用来确定排序的方式。

先以整型递增排序为例

int inc (const void * a,const void *b)
 {
return * (int * )a-* (int *)b;
}
  1. int inc 表示函数返回一个int值。inc为函数名 ,表示递增排序(increase),也可以自己命名。
  2. ( const void * a, const void * b)将两个要对比的元素的地址传入函数。 (加const表示无法改变指针指向的值)
  3. return * ( int * )a - * ( int * ) b ,返回一个整型数,表示两个元素对比的结果。如果a大于b,则返回正数。a小于b,则返回负数。如果a等于b,则返回零。(int )表示将地址强制类型转换成整形地址类型,可根据排序对象选择指针类型的转换。也可以改变算式,例如用 return strlen((char )a) > strlen((char * )b) ? 1 : -1; 可以返回比较字符串长度的结果,用来根据字符串长度进行排序, 下面有相关的代码。

下面为各种数据类型的升序排序函数

(如果要降序排序,只需将return里的a,b反过来写即可。)

  1. 整型

    int inc (const void * a,const void *b)
    {
    return *(int *)a - *(int *)b;
    }
    
  2. double型

    int inc (const void * a, const void * b)
    {
    return *(double *)a > *(double *)b ? 1 : -1;
    }
    

    注: 这里两个浮点数相减但要返回一个整型数,如果按上面做法直接减会丢失小数点部分。所以需另加处理,直接判断大小,如果a大于b,则返回1,否则返回-1。

  3. 字符排序

    int inc(const void *a,const void *b)
    {
      return *(char *)a - *(char *)b;
    }
  4. 字符串排序

    扫描二维码关注公众号,回复: 1028522 查看本文章
    char am = { {"...."}, {"....."}, .....};
    qsort(a, m, sizeof(char * )  * n, inc);
    1. 根据字符串首字母排序

      int inc(const void *a, const void *b)  
      {  
      return * (char *)a - *(char * )b;  
      }  
    2. 根据字符串长度排序

      int inc(const void *a, const void *b)  
      {  
      return strlen((char * )a) > strlen((char * )b) ? 1 : -1;  
      } 

      注:这里不要用 return strlen((char * )a) - strlen((char * )b) ;
      原因:

      1. strlen返回类型为size_t,size_t是标准C库中定义的,应为unsigned int,在64位系统中为 long unsigned int。无符号整型最好不要做四则运算。
      2. 这里虽然函数返回int型,会把无符号数转换为整型,但返回结果只在字符串的长度未超过int的范围时正确。这种大范围转小范围要考虑精度损失的问题。
    3. 按字典排序字符串。

      int inc(const void *a, const void *b)
      {
      return (strcmp((char *)a, (char *)b));
      }
  5. 结构体

    struct node
    {
      double one;
      int two;
    } s[100];

    1.一级排序
    根据double型的one的大小排序结构体。

    int inc( const void *a ,const void *b)
    {
    return ( * (node * )a).one > ( * (node * )b).one ? 1 : -1;
    }


    2.二级排序
    先根据double型的one的大小排序,若两值相等,在根据int型two的大小排序。

    int inc( const void *a , const void *b )
    {
    if((* (node * )a).one != ( * (node * )b).one)
    return ( * (node * )a).one > ( * (node * )b).one ? 1 : -1;
    else return (* (node * )a).two -( * (node * )b).two;
    }

    快速排序是不稳定的排序,若想提升其稳定性,可以在结构里加一个int numb,用来记录排序开始时前的顺序。如果if对比的值都相等,则可以else return ……根据numb再进行排序。

具体样例

整型

#include<stdio.h>
#include<stdlib.h>
#define L 20
int inc(const void *a, const void *b)
{
    return *(int *)a - *(int *)b;
 } 
int main ()
{
    int a[L] = {0, 5, 2, 3, 4, 9, 8, 7, 6, 1,
        11, 15, 14, 12, 13, 16, 17, 18, 19, 10};
    qsort(a, L, sizeof(int), inc);
    for (int i = 0; i < L; i++)
    {
        printf("%d ", a[i]);
    }
 } 

整型结果

double型

#include<stdio.h>
#include<stdlib.h>
#define L 20
int inc(const void *a, const void *b)
{
    return *(double *)a > *(double *)b? 1 : -1;
 } 
int main ()
{
    double a[L] = {0.1, 0.11, 1.1, 1.5, 1.8, 1.51, 2.5, 2.9, 1.3, 0.8, 
        15.5, 7.9, 8.5, 8.51, 8.6, 3, 1.41, 1.11, 1.51, 2};
    qsort(a, L, sizeof(double), inc);
    for (int i = 0; i < L; i++)
    {
        printf("%.2lf\n", a[i]);
    }
 } 

运行结果 :
double

字符型

#include<stdio.h>
#include<stdlib.h>
#define L 20
int inc(const void *a, const void *b)
{
    return *(char *)a - *(char *)b;
 } 
int main ()
{
    char a[L] = {'q', 'w', 'r', 'h', 'a', 'v', 'g', 'e', 'b', 'l',
        'o', 'p', 'u', 'y', 't', 'c', 'x', 'i', 'z', 's'};
    qsort(a, L, sizeof(char), inc);
    for (int i = 0; i < L; i++)
    {
        printf("%c ", a[i]);
    }
 } 

运行结果 :
这里写图片描述

字符串
1. 按首字母排序

#include<stdio.h>
#include<stdlib.h>
#define L 10
#define K 10
int inc(const void *a, const void *b)
{
    return *(char *)a - *(char *)b;
 } 
int main ()
{
    char a[L][K] = {
        "rbsc",
        "jcse",
        "efgd",
        "arbs",
        "bbs",
        "cbfe",
        "dgafg" ,
        "ewqrta",
        "ofgd",
        "mbcv",
    };
    qsort(a, L, sizeof(char) * K, inc);
    for (int i = 0; i < L; i++)
    {
        printf("%s\n", a[i]);
    }
 } 

运行结果 :
这里写图片描述

  1. 按长度排序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define L 10
#define K 10
int inc(const void *a, const void *b)
{
    return strlen((char *)a) > strlen((char *)b) ? 1 : -1;
 } 
int main ()
{
    char a[L][K] = {
        "rbsc",
        "jcsse",
        "efgdsd",
        "arbs",
        "bbs",
        "cbfefaa",
        "dgafg" ,
        "ewqrta",
        "ofgd",
        "mbcv312",
    };
    qsort(a, L, sizeof(char) * K, inc);
    for (int i = 0; i < L; i++)
    {
        printf("%s\n", a[i]);
    }
 } 

运行结果 :
这里写图片描述
3. 按字典顺序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define L 10
#define K 10
int inc(const void *a, const void *b)
{
    return strcmp((char * )a, (char *)b);
 } 
int main ()
{
    char a[L][K] = {
        "rbsc",
        "jcsse",
        "afgdsd",
        "arbs",
        "abs",
        "cbfefaa",
        "cgafg" ,
        "ewqrta",
        "ofgd",
        "mbcv312",
    };
    qsort(a, L, sizeof(char) * K, inc);
    for (int i = 0; i < L; i++)
    {
        printf("%s\n", a[i]);
    }
 } 

运行结果:
这里写图片描述
结构体
结构体二级稳定排序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define L 10
typedef struct node {
    double first;
    int numb;
 }node;

int inc(const void *a, const void *b)
{
    if((* (node *)a).first != ( * (node *)b).first)
    return ( * (node * )a).first > ( * (node * )b).first ? 1 : -1;
    else return (* (node * )a).numb -( * (node * )b).numb;

 } 

int main ()
{
    node arr[L] = {
        1.0, 1,
        2.0, 2,
        1.1, 3,
        2.1, 4,
        3.5, 5,
        1.0, 6,
        1.1, 7,
        5.1, 8,
        5.0, 9,
        3.6, 10,

    };
    qsort(arr, L, sizeof(node), inc);
    for (int i = 0; i < L; i++)
    {
        printf("%.2lf %d\n", arr[i].first, arr[i].numb);
    }
 } 

运行结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/z944733142/article/details/80292613