qsort函数 - (Quick Sort)【快速排序的使用方法】

简介: qsort函数 - (Quick Sort)【快速排序的使用方法】

什么是qsort函数

qsort - Quick Sort

是c语言中一种用于排序的函数,这种方法也叫作快速排序法。

它与冒泡排序不同,冒泡排序是一种算法,而qsort是c语言中编译器函数库自带的排序函数,存在于stdlib.h文件中。

qsort 函数可以根据使用者的不同需求快速的实现不同数据的排序。


qsort函数的使用方法

在c语言的学习中,我们需要 “善假于工具”,在cplusplus中,提供了qsort函数的使用方法以及功能参数等

功能


参数

使用方法

根据 cplusplus 提供的参数以及功能,能大致了解qsort的使用方法。

存在一个整形数组arr,且数组内的元素均为整形。

现在需要使用qsort函数 - 快速排序 将数组内的元素进行排序:

#include<stdio.h>
test1()
{
   int arr[] = {9,8,7,6,5,4,3,2,1,0};//整形数组
}
int main()
{
   test1();
   return 0;
}

根据cplusplus给出的参数,可以知道,在qsort中所需要的参数为:

  • 指向数组首元素地址的指针;
  • 数组内的元素个数;
  • 数组内各个元素的大小;
  • 以及可以用来判断两个数大小的函数compar( ),且该函数的返回值为int;

指向数组首元素地址的指针:

根据数组名即为首元素地址(大多数情况下),得出在传入第一个参数时,可以传入需要排列数组的数组名。

数组内元素个数:

第二个参数 - size_t num 需要排列数据的个数,即数组元素个数 - sizeof(arr) / sizeof(arr[0])

即用数组总大小除以数组内单个元素大小。

数组内各个元素大小:

第三个参数,size_tsize,需要排列的数组内元素的大小 - sizeof(arr[0])

comper函数:

除了前三个参数,还需要一个函数指针

int (*compar)(const void*,const void*));

该指针指向的函数可以用来接收数组内两个需要比较的数据的地址,并返回整形值若两个数比较(p1,p2),p1对应的值>p2对应的值,返回大于0的数;p1对应的值==p2对应的值,则返回0;p1对应的值<p2对应的值,则返回小于0的数。故在使用qsort函数的同时,也需创建一个同样类型的函数,根据需要返回的值进行判断,在进行排序整形时,只需要作差即可 (默认为升序,若是需要降序则将p1,p2位置调换即可)。

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

在这里也有个疑问,在使用数据时为什么需要将p1,p2进行强转类型呢?

在该函数的创建过程中,因为不能保证使qsort函数的使用者进行什么类型的排序,所以在函数创建的过程中,参数使用了void*(可接收任意类型的指针)进行接收;再者,该类型的指针不能直接进行解引用操作(erro - 非法间接访问),故在使用时需要进行强制类型转换。


下列代码为排列整形数据的例子:

void print(int arr[], int sz)
{
  //打印函数
  for (int i = 0; i < sz; i++) {
    printf("%d ", arr[i]);
  }
}
int compar(void* p1, void* p2)
{
  //该函数需要使用者自行创建
  return *(int*)p1 - *(int*)p2;
}
void test1()
{
  int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
  int sz = sizeof(arr) / sizeof(arr[0]);//数组内元素个数
  qsort(arr, sz, sizeof(arr[0]), compar);
  print(arr,sz);//打印函数
}
int main()
{
  test1();
  return 0;
}

qsort函数排序其他

qsort为不仅可以排序整形,还可以排序浮点型、字符型、字符串型、结构体类型等等…


qsort排序浮点型

int compar_by_float(void* p1, void* p2)
{
  if (*(float*)p1 == *(float*)p2) {
    return 0;
  }
  return *(float*)p1 > * (float*)p2 ? 1 : -1;
}
void print(float flArr[], int sz)
{
  for (int i = 0; i < sz; i++) {
    printf("%.2f ", flArr[i]);
  }
}
void test3()
{
  //排列浮点型数据
  float flArr[] = { 2.0f, 3.5f, 4.8f, 1.2f, 0.9f, 6.6f, 4.4f, 1.6f, 0.2f };
  int sz = sizeof(flArr) / sizeof(flArr[0]);
  qsort(flArr, sz, sizeof(flArr[0]), cmp_by_float);
  print(flArr,sz);
}
int main()
{
  test3();//浮点类型数据
  return 0;
}

浮点型数据在compar函数中,若是作差再使用int进行返回时,会出现精确丢失,所以不可作差;

可采用两种方式:一是使用if判断进行返回,二是将返回类型改为double型;

//           一  
int compar_by_float(void* p1, void* p2)
{
  if (*(float*)p1 == *(float*)p2) {
    return 0;
  }
  return *(float*)p1 > * (float*)p2 ? 1 : -1;
}
//--------------------------------------------------
//           二  
double compar_by_float(void* p1, void* p2)
{
  return *(float*)p1 - *(float*)p2) ;
}

qsort排序结构体类型 - 字符串

struct Stu 
{
  char name[20];
  int age;
};
print(struct Stu s[], int sz)
{
  for (int i = 0; i < sz; i++) {
    printf("%s ", s[i].name);
  }
}
int cmp_str_name(void* p1, void* p2)
{
  return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
void test2()
{//排列结构体类型数据
  struct Stu s[5] = { {"Xiaoli",52} ,{"Zhangqiang",28}, {"Milaotou",66}, {"Mazi",35}, {"Wangwu",26} };
  int sz = sizeof(s) / sizeof(s[0]);
  qsort(s,sz,sizeof(s[0]),cmp_str_name);
  print(s,sz);
}
int main()
{
  test2();//结构体 字符串
  return 0;
}

字符串类型的比较大小不可用 < , > , == 进行比较,只能使用strcmp( )函数进行比较,而比较的结果与qsort函数所需的返回值相同

故可以直接作为返回类型。

int cmp_str_name(void* p1, void* p2)
{
  return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}

结构体类型 - 整形 同理。


相关文章
|
7月前
|
算法 机器人 定位技术
【VRPTW】基于matlab秃鹰算法BES求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)(Matlab代码实现)
【VRPTW】基于matlab秃鹰算法BES求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)(Matlab代码实现)
233 0
|
6月前
|
机器学习/深度学习 传感器 算法
基于matlab瞬态三角哈里斯鹰算法TTHHO多无人机协同集群避障路径规划(目标函数:最低成本:路径、高度、威胁、转角)(Matlab代码实现)
基于matlab瞬态三角哈里斯鹰算法TTHHO多无人机协同集群避障路径规划(目标函数:最低成本:路径、高度、威胁、转角)(Matlab代码实现)
249 1
|
7月前
|
机器学习/深度学习 算法 数据挖掘
【配送路径规划】基于螳螂虾算法MShOA求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)研究(Matlab代码实现)
【配送路径规划】基于螳螂虾算法MShOA求解带时间窗的骑手外卖配送路径规划问题(目标函数:最优路径成本 含服务客户数量 服务时间 载量 路径长度)研究(Matlab代码实现)
289 0
|
7月前
|
算法 Python
【配送路径规划】基于遗传算法求解带时间窗的电动汽车配送路径规划(目标函数:最小成本;约束条件:续驶里程、额定载重量、数量、起始点)研究(Matlab代码实现)
【配送路径规划】基于遗传算法求解带时间窗的电动汽车配送路径规划(目标函数:最小成本;约束条件:续驶里程、额定载重量、数量、起始点)研究(Matlab代码实现)
258 0
|
搜索推荐 C语言
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
694 4
|
11月前
|
算法 搜索推荐
快速排序-数据结构与算法
快速排序(Quick Sort)是一种基于分治法的高效排序算法。其核心思想是通过选择基准(pivot),将数组划分为左右两部分,使得左侧元素均小于基准,右侧元素均大于基准,然后递归地对左右两部分进行排序。时间复杂度平均为 O(n log n),最坏情况下为 O(n²)(如数组已有序)。空间复杂度为 O(1),属于原地排序,但稳定性不佳。 实现步骤包括编写 `partition` 核心逻辑、递归调用的 `quickSort` 和辅助函数 `swap`。优化方法有随机化基准和三数取中法,以减少最坏情况的发生。
719 13
|
搜索推荐 Python
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
331 67
|
存储 搜索推荐 Python
用 Python 实现快速排序算法。
快速排序的平均时间复杂度为$O(nlogn)$,空间复杂度为$O(logn)$。它在大多数情况下表现良好,但在某些特殊情况下可能会退化为最坏情况,时间复杂度为$O(n^2)$。你可以根据实际需求对代码进行调整和修改,或者尝试使用其他优化策略来提高快速排序的性能
380 61
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
566 1
|
5月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
548 0

热门文章

最新文章