C语言 | qsort()函数使用

目录:

1.qsort介绍

2.使⽤qsort函数 排序 整型数据

3.使⽤qsort函数 排序 结构体数据

  1. qsort函数的模拟实现冒泡排序

qsort()函数 是一个 C语言编译器函数库自带的排序函数, 它可以对指定数组(包括字符串,二维数组,结构体等)进行排序。

头文件:<stdlib.h>

qsort函数原型

cs 复制代码
void qsort(
      void *base, //指针,指向的是待排序的数组的第一个元素
      size_t num, //是base指向的待排序数组的元素个数
      size_t size, //base指向的待排序数组的元素的大小(字节数)
      int (*compar)(const void *, const void *) //函数指针
    );

compar参数是qsort函数排序的核心内容,它指向一个比较两个元素的函数,注意两个形参必须是const void *型,同时在调用compar 函数(compar实质为函数指针,这里称它所指向的函数也为compar)时,传入的实参也必须转换成const void *型。在compar函数内部会将const void *型转换成实际类型。

如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的前面 。如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不变 。如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的后面 。

因此,如果想让qsort()进行从小到大(升序)排序, 那么一个通用的compar函数可以写成这样:

cs 复制代码
int compare (const void * a, const void * b)
 {
   if ( *(MyType*)a <  *(MyType*)b )
     return -1;
   if ( *(MyType*)a == *(MyType*)b )
     return 0;
   if ( *(MyType*)a >  *(MyType*)b ) 
     return 1;
 }

如果你要将MyType换成实际数组元素的类型。 可以:

cs 复制代码
//升序排序
 int compare (const void * a, const void * b)
 {
     return ( *(int*)a - *(int*)b );//强制类型转换后,进行访问
 }

//降序排列
 int compare (const void * a, const void * b)
 {
     return ( *(int*)b - *(int*)a );
 }

1.使⽤qsort函数 排序整型数据

2.使⽤qsort排序 结构体数据

cs 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Stu //学⽣
{
 char name[20];//名字
 int age;//年龄
};

//假设按照年龄来⽐较
int cmp_stu_by_age(const void* e1, const void* e2)
{
 return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//结构体变量.成员名
//结构体指针->成员名

//假设按照名字来⽐较
int cmp_stu_by_name(const void* e1, const void* e2)
{
 return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//strcmp - 是库函数,是专⻔⽤来⽐较两个字符串的⼤⼩的
           //是按照对应字符串中字符的ASCII码值比较的

//按照年龄来排序
void test2()
{
 struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };
 int sz = sizeof(s) / sizeof(s[0]);
 qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}

//按照名字来排序
void test3()
{
 struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };
 int sz = sizeof(s) / sizeof(s[0]);
 qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}

int main()
{
 test2();//按照年龄来排序
 test3();//按照名字来排序
 return 0;
}
  1. qsort函数的模拟实现冒泡排序

使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)

cs 复制代码
#include <stdio.h>

int int_cmp(const void * p1, const void * p2)
{
  return (*( int *)p1 - *(int *) p2);
}

void swap(void *p1, void * p2, int size)
//交换两个元素
                              //void*的指针 是无具体类型的指针
{                             //作用是接收任何类型的地址  
   int i = 0;
   for (i = 0; i< size; i++)
 {
              char tmp = *((char *)p1 + i);
    *(( char *)p1 + i) = *((char *) p2 + i);
    *(( char *)p2 + i) = tmp;
 }
}
void bubble(void *base, int count , int size, int(*cmp )(void *, void *))
{
    int i = 0;
    int j = 0;
   for (i = 0; i< count - 1; i++)
  {
    for (j = 0; j<count-i-1; j++)
   {                            //实现升序看 是否>0 是否进行交换
    if (cmp ((char *) base + j*size , (char *)base + (j + 1)*size) > 0)
    {       
          //相当于冒泡排序中的arr[j]与arr[j+1]

     swap(( char *)base + j*size, (char *)base + (j + 1)*size, size);
    }
   }
  }
}
  int main()
 {
  int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
  int i = 0;
  bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
  //自制冒泡排序
 for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
 {
   printf( "%d ", arr[i]);//实现升序排列
 }
 printf("\n");
 return 0;
}

分享到这里,感谢观看

相关推荐
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
网易独家音乐人Mike Zhou3 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
冰帝海岸4 小时前
01-spring security认证笔记
java·笔记·spring
----云烟----5 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024065 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
小二·5 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it5 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康5 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神6 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式