快排函数 -- qsort函数(Quick Sort)

简介: 快排函数 -- qsort函数(Quick Sort)

🔎1.qsort函数简介

👁️qsort()函数是C语言库函数中的一种排序算法,其用到的排序思想是快速排序(quicksort)。它的独特之处在于可以排序任意类型的数组元素(整型、浮点型、字符串和结构体类型)

可以参考一下 cplusplus 中的资料👇

de0b7d9ecd2b4996a7ceade460739ca6.png

💡1.1.函数原型

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


💡1.2.参数含义

🔴void * base :指向了待排序数组的第一个元素(待排序数组的首地址)

🔴size_t num :待排序的元素个数

🔴size_t size : 每个元素的大小(单位是字节)

🔴int ( * compar ) ( const void * , const void * ) :是一个函数指针,指向一个函数,这个函数可以比较两个元素的大小

可以再参考一下 cplusplus 中的资料👇

a12ee81997b242f1a7aaa7ee5124387b.png


🔎2.比较函数介绍

🔴使用qsort来排序整型数组,这里就由qsort函数的使用者来提供一个比较函数(自定义函数),这个比较函数能够比较2个整数的大小


🔴两个参数表示所要比较元素的地址,之所以参数的接收类型为 void*(无具体类型指针) 是因为它可以接收任意类型的地址,比较元素的类型是不清楚的,只能以 void* 这个万能桶进行接收;const表示指针所指向元素的值无法更改


🔴因为void* 的指针不能解引用操作,所以要对两个元素指针进行强制类型转化为整型指针,再进行解引用获取比较元素的值,最后将两个元素的差值返回。当然也可以根据比较元素的类型将其强制类型转化


🔴compar比较函数的返回值,<0(不进行置换),>0(进行置换),==0(不进行置换)

p1 - p2 升序

p2 - p1 降序


🔎3.比较函数使用案例

💡3.1.整型数组

#include<stdio.h>
#include<stdlib.h>
//qsort函数的使用者提供这个比较函数
int cmp_int(const void* p1, const void* p2)//void* - 无具体类型指针,所以它可以接收任意类型的地址
{
  return *(int*)p1 - *(int*)p2;
}
void print_arr(int arr[], int sz)
{
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    printf("%d ", arr[i]);
  }
  printf("\n");
}
test1()
{
  int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  //使用qsort来排序整型数组,这里就要提供一个比较函数,这个比较函数能够比较2个整数的大小
  //qsort 默认是排成升序的
  qsort(arr, sz, sizeof(arr[0]), cmp_int);
  print_arr(arr, sz);
}
int main()
{
  test1();
  return 0;
}

8e71ce46aafd4063947f81912631dd81.png

💡3.2.浮点型数组

#include<stdio.h>
#include<stdlib.h>
//qsort 排序浮点型数据
int cmp_double(const void* p1, const void* p2)
{
  return *(double*)p1 > *(double*)p2 ? 1 : -1;
}
void print_arr(double arr[], int sz)
{
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    printf("%.2lf ", arr[i]);
  }
  printf("\n");
}
void test2()
{
  //排列浮点型数据
  double arr[] = { 2.0 ,3.5 ,4.8 ,1.2 ,0.9 ,6.6 ,4.4 ,1.6 ,0.3 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  qsort(arr, sz, sizeof(arr[0]), cmp_double);
  print_arr(arr, sz);
}
int main()
{
  test2();
  return 0;
}

8174b5d286f049368f805c23471aafa0.png

🚨此函数返回类型为 int 型,浮点型相减的数字会丢失小数点后的数字从而造成误差。若差值为大于0且小于1,则返回值会被设置为0

💡3.3.结构体类型 - 字符串

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//qsort 排序结构体数据
struct Stu
{
  char name[20];
  int age;
};
//按照年龄来比较
int cmp_stu_by_age(const void* p1, const void* p2)
{
  return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}
//按照名字来比较
int cmp_stu_by_name(const void* p1, const void* p2)
{
  return strcmp(((struct Stu*)p1)->name , ((struct Stu*)p2)->name);
}
void test3()
{
  struct Stu s[] = { {"zhangsan",30},{"lisi",25},{"wangwu",50}};
  int sz = sizeof(s) / sizeof(s[0]);
  //测试按照年龄来排序
  qsort(s,sz,sizeof(s[0]),cmp_stu_by_age);
  //测试按照名字来排序
  qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
  test3();
  return 0;
}

🚨按照名字来比较时是比较字符串类型大小,比较字符串类型大小不可用 < ,> , == 进行比较,需要使用 strcmp() 函数进行比较,而比较的结果与 qsort函数所需的返回值相同

5880579b090c43bba713201e9c512d39.png

使用 qsort函数 不要忘记引头文件 <stdlib.h>‼️

🔎4.利用冒泡排序模拟实现qsort函数的功能

请看源码和注释👇

#include<stdio.h>
//qsort函数的使用者提供这个函数
int cmp_int(const void* p1, const void* p2)
{
  return *(int*)p1 - *(int*)p2;
}
void print_arr(int arr[], int sz)
{
  int i = 0;
  for (i = 0; i < sz; i++)
  {
    printf("%d ", arr[i]);
  }
  printf("\n");
}
void Swap(char* buf1, char* buf2, int width)
{
  int i = 0;
  for (i = 0; i < width; i++)
  {
    char tmp = *buf1;
    *buf1 = *buf2;
    *buf2 = tmp;
    buf1++;
    buf2++;
  }
}
//假设排序为升序
//希望这个bubble_sort函数可以排序任意类型的数据
void bubble_sort(void* base, size_t num, size_t width, int(*cmp)(const void* p1, const void* p2))
{
  //要确定趟数
  size_t i = 0;
  for (i = 0; i < num - 1; i++)
  {
    //一趟冒泡排序的过程
    size_t j = 0;
    for (j = 0; j < num - 1 - i; j++)
    {
      //两个相邻的元素比较
      //arr[j]  arr[j+1]
      if (cmp((char*)base+j*width,(char*)base+(j + 1)*width) > 0)
      {
        //交换
        Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
      }
    }
  }
}
void test4()
{
  int arr[] = { 3,1,5,2,4,0,9,8,6,7 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
  print_arr(arr, sz);
}
int main()
{
  test4();
  return 0;
}

3a1cb3a26546438989dc1743f3490eea.png

目录
相关文章
|
7天前
|
搜索推荐 算法 Java
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
该博客文章通过UML类图和Java源码示例,展示了如何使用适配器模式将QuickSort类和BinarySearch类的排序和查找功能适配到DataOperation接口中,实现算法的解耦和复用。
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
|
1月前
|
算法 Python
`scipy.optimize`模块提供了许多用于优化问题的函数和算法。这些算法可以用于找到函数的最小值、最大值、零点等。
`scipy.optimize`模块提供了许多用于优化问题的函数和算法。这些算法可以用于找到函数的最小值、最大值、零点等。
|
2月前
|
算法 Java C语言
Java中的算法与C语言中的函数
Java中的算法与C语言中的函数
27 2
|
2月前
|
算法 调度 C++
【调度算法】共享函数vs拥挤距离
【调度算法】共享函数vs拥挤距离
34 1
|
1月前
|
算法 安全 数据安全/隐私保护
支付系统---微信支付09------数字签名,现在Bob想要给Pink写一封信,信件的内容不需要加密,怎样能够保证信息的完整性,使用信息完整性的主要手段是摘要算法,散列函数,哈希函数,H称为数据指纹
支付系统---微信支付09------数字签名,现在Bob想要给Pink写一封信,信件的内容不需要加密,怎样能够保证信息的完整性,使用信息完整性的主要手段是摘要算法,散列函数,哈希函数,H称为数据指纹
|
2月前
|
算法 vr&ar
技术好文共享:遗传算法解决函数优化
技术好文共享:遗传算法解决函数优化
|
2月前
|
算法 C语言 Python
简单遗传算法优化简单一元函数(python)
简单遗传算法优化简单一元函数(python)
22 0
|
2月前
|
算法
数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)
数据结构和算法学习记录——初识二叉树(定义、五种基本形态、几种特殊的二叉树、二叉树的重要性质、初识基本操作函数)
19 0
|
2月前
|
存储 算法
数据结构和算法学习记录——特殊线性表之队列-队列的概念、队列结构体类型定义 、基本接口函数、初始化函数、销毁队列函数、入队列函数、判断队列是否为空、出队列函数、读取队头队尾的数据 、计算队列数据个数
数据结构和算法学习记录——特殊线性表之队列-队列的概念、队列结构体类型定义 、基本接口函数、初始化函数、销毁队列函数、入队列函数、判断队列是否为空、出队列函数、读取队头队尾的数据 、计算队列数据个数
24 0
|
2月前
|
算法 C语言
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
数据结构和算法学习记录——特殊线性表之栈(下)-销毁栈函数、判断栈是否为空、压栈函数、出栈函数、取栈顶元素、计算栈中有多少个元素、栈有关习题-有效的括号
20 0

热门文章

最新文章