qsort函数原型

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

  头文件:<stdlib.h>

  函数功能:qsort()函数的功能是对数组进行排序,数组有nmemb个元素,每个元素大小为size。

  参数base - base指向数组的起始地址,通常该位置传入的是一个数组名

  参数nmemb - nmemb表示该数组的元素个数

  参数size - size表示该数组中每个元素的大小(字节数)

  参数(*compar)(const void *, const void *) - 此为指向比较函数的函数指针,决定了排序的顺序。

  函数返回值:无

  注意:如果两个元素的值是相同的,那么它们的前后顺序是不确定的。也就是说qsort()是一个不稳定的排序算法。

compar参数

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

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

  如果compar返回值小于0(< 0),那么p1所指向元素会被排在p2所指向元素的前面

  如果compar返回值等于0(= 0),那么p1所指向元素与p2所指向元素的顺序不确定

  如果compar返回值大于0(> 0),那么p1所指向元素会被排在p2所指向元素的后面

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

 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换成实际数组元素的类型。

  或者

//升序排序
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 );
}

int 数组排序

/* qsort example */
#include <stdio.h>
#include <stdlib.h> int values[] = { 40, 10, 100, 90, 20, 25 }; int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
} int main ()
{
int n;
qsort (values, sizeof(values)/sizeof(values[0]), sizeof(int), compare);
for (n=0; n<sizeof(values)/sizeof(values[0]); n++)
printf ("%d ",values[n]);
return 0;
}

结构体排序

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
// void qsort(void* base, size_t num, size_t size, int(*compare)(const void*, const void*)) typedef struct
{
char name[30]; // 学生姓名
int Chinese; // 语文成绩
int Math; // 数学成绩
int English; // 英语成绩
}st;
int cmp(const void* a, const void* b)
{
st* pa = (st*)a;
st* pb = (st*)b;
int num1 = pa->Chinese + pa->English + pa->Math;
int num2 = pb->Chinese + pb->English + pb->Math; //return (int)num1 - num2; // 从小到大,
return (int)num2 - num1; // 从大到小
}
int main(void)
{
st students[7] = {
{"周",97,68,45},
{"吴",100,32,88},
{"郑",78,88,78},
{"王",87,90,89},
{"赵",87,77,66},
{"钱",59,68,98},
{"孙",62,73,89}
};
qsort(students, 7, sizeof(st), cmp); // 注意区别 students 与 st for (int i = 0; i < 7; i++)
{
printf("%s%4d%4d%4d\t", students[i].name, students[i].Chinese, students[i].Math, students[i].English);
printf("总分:%d\n", students[i].Chinese + students[i].English + students[i].Math);
} system("pause");
return 0;
}

字符串指针数组排序

#include <stdio.h>
#include <string.h>
#include <stdlib.h> int compare(const void *arg1, const void *arg2); int
main(int argc, char** argv)
{
int i; char *arr[5] = { "i", "love", "c", "programming", "language" }; qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(char *), compare); for (i = 0; i < 5; i++) {
printf("%s ", arr[i]);
}
printf("\n"); } int compare(const void *arg1, const void *arg2) {
char *a = *(char**)arg1;
char *b = *(char**)arg2;
int result = strcmp(a, b);
if (result > 0) {
return 1;
}
else if (result < 0) {
return -1;
}
else {
return 0;
}
}

  那么我们向qsort传入arr之后,qsort将arr理解为指向数组中第一个元素的指针,所以形参表中,arg1和arg2其实是指向“指向常量字符串的指针”的指针,是char**。而我们需要传给strcmp这个字符串比较函数的,是“指向字符串的指针”,是char*,所以我们将void*转换为char**,然后解引用,得到char*,赋予a和b。接下来使用strcmp对a和b进行比较。(数组名本身算一层指针,而里面的内容又是一层指针,数组存放的是指向字符串的地址)

字符串二维数组排序

#include <stdio.h>
#include <string.h>
#include <stdlib.h> int compare(const void *arg1, const void *arg2); int
main(int argc, char** argv)
{
int i; char arr[5][16] = { "i", "love", "c", "programming", "language" }; qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), compare);
printf("%s\n", arr[0]);
for (i = 0; i < 5; i++) {
printf("%s ", arr[i]);
}
printf("\n");
} int compare(const void *arg1, const void *arg2) {
char *a = (char*)arg1;
char *b = (char*)arg2;
int result = strcmp(a, b);
if (result > 0) {
return 1;
}
else if (result < 0) {
return -1;
}
else {
return 0;
}
}

  这里对二维数组进行排序,其实是对二维数组的第二维中存放的字符串进行排序。所以qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), compare);对qsort函数的调用中,第二个参数是待排元素的个数(5个),第三个参数是待排元素的大小(16)。

  我们将arr传入qsort函数,qsort函数将arr理解为指向数组第一个元素的指针,arr的第一个元素是arr[0][0],所以参数arg1和arg2指的是指向"a[i][0]"的指针,我们知道,a[i][0]是字符,就是char,所以arg1和arg2指的是char *。我们将void*转换为char*,赋予a和b,调用strcmp函数对a和b进行比较。

整型二维数组(力扣题目)

  1. 最接近原点的 K 个点

  我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。(这里,平面上两点之间的距离是欧几里德距离。)你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。

示例 1:

输入:points = [[1,3],[-2,2]], K = 1

输出:[[-2,2]]

解释: (1, 3) 和原点之间的距离为sqrt(10), (-2, 2) 和原点之间的距离为 sqrt(8), 由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。 我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]。

示例 2:

输入:points = [[3,3],[5,-1],[-2,4]], K = 2

输出:[[3,3],[-2,4]] (答案 [[-2,4],[3,3]] 也会被接受。)

提示:

1 <= K <= points.length <= 10000

-10000 < points[i][0] < 10000

-10000 < points[i][1] < 10000

/* qsort排序二维数组,cmp的每个元素都是一个独立的 int 数组,也就是指针 */
int cmp(const void* a, const void* b) { // 转换为对应一维数组
int* arry1 = *(int**)a;
int* arry2 = *(int**)b; // 获取对应arry1 的两个元素
int x1 = *arry1;
int y1 = *(arry1 + 1); int x2 = *arry2;
int y2 = *(arry2+1); return (x1*x1 + y1*y1) - (x2*x2 + y2*y2);
} int** kClosest(int** points, int pointsSize, int* pointsColSize, int K, int* returnSize, int** returnColumnSizes){
if(points==NULL || pointsSize==0 || K==0) return NULL; qsort(points, pointsSize, sizeof(int)*pointsColSize[0], cmp);
/* 这里注意 qsort 的传参,使用不当会报错
Line 11: Char 11: runtime error: load of misaligned address 0x602000000032 for type 'int *', which requires 8 byte alignment (solution.c) 0x602000000032: note: pointer points here
*/ // 指定return输出的二维数组是包含有几个一维数组
*returnSize = pointsSize > K ? K : pointsSize; *returnColumnSizes = (int*)malloc(sizeof(int*)*(*returnSize));
// 指定每个一维数组的 col
for(int i = 0; i< (*returnSize); i++) {
(*returnColumnSizes)[i] = 2;
}
return points;
}

有任何问题,均可通过公告中的二维码联系我

qsort函数使用方法总结(详细全面+代码)的更多相关文章

  1. qsort函数以及sort函数使用方法

     sort函数的使用方法 做ACM题的时候,排序是一种常常要用到的操作. 假设每次都自己写个冒泡之类的O(n^2)排序,不但程序easy超时,并且浪费宝贵的比赛时间,还非常有可能写错. STL里面 ...

  2. jQuery Ajax方法调用 Asp.Net WebService、WebMethod 的详细实例代码

    将以下html存为ws.aspx <%@ Page Language="C#" AutoEventWireup="true" %> <scri ...

  3. C语言函数qsort的使用方法

    qsort函数stdlib.h文件中,函数原型为 void qsort(void *base,size_t nelem,size_t width,int (*Comp)(const void *,co ...

  4. 【C/C++】qsort函数的使用方法和细节

    函数概述 qsort 为quick_sort的简写,意为快速排序,主要用于对各种数组的排序. 因为数组的元素可能是任何类型的,甚至是结构或者联合,所以必须高数函数qsort如何确定两个数组元素哪一个& ...

  5. Oracle数据库中调用Java类开发存储过程、函数的方法

    Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日  浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...

  6. 学习笔记:jquery1.9版本后废弃的函数和方法

    jQuery1.9+ 废弃的函数和方法 升级Jquery版本遇到的问题 (转载自:http://www.ppblog.cn/jquery1-9live.html  版权归原作者所有) jQuery1. ...

  7. python函数与方法装饰器

    之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...

  8. qsort()函数详解

    一 写在开头1.1 本节内容学习C语言中的qsort()函数. 二 qsort()2.1 函数原型 void qsort( void *base, size_t nmemb, size_t size, ...

  9. qsort函数排序各种类型的数据。

    qsort函数是库函数中的一员,我们先来看看官方文档是怎么写的: 其中qsort的参数void* base是传入一个数组,size_t num 为数组整体大小,size_t size 为单个元素的大小 ...

  10. 对于Python函数与方法,你可能存在些误解

    欢迎添加华为云小助手微信(微信号:HWCloud002 或 HWCloud003),输入关键字"加群",加入华为云线上技术讨论群:输入关键字"最新活动",获取华 ...

随机推荐

  1. 湖南省网络攻防邀请赛 RE 题解

    ez_apkk 解题过程: 将apk拖入jadx,查看MainActivity,发现是简单RC4加密,密钥是"55667788",最后再将加密结果+1 public String ...

  2. springcloud 实体类使用@Builder@AllArgsConstructor两个注解后查询执行操作时报数据转换异常

    异常日志如下: org.springframework.jdbc.UncategorizedSQLException: Error attempting to get column 'DATA_SOU ...

  3. Vue2.0 学习 第二组 语法模板

    本笔记主要参考菜鸟教程和官方文档编写. 1.文本绑定 一般在dom中用{{}}标时,并且在vue构造体内的data中定义文本内容 <div id="app">    & ...

  4. 在灾难推文分析场景上比较用 LoRA 微调 Roberta、Llama 2 和 Mistral 的过程及表现

    引言 自然语言处理 (NLP) 领域的进展日新月异,你方唱罢我登场.因此,在实际场景中,针对特定的任务,我们经常需要对不同的语言模型进行比较,以寻找最适合的模型.本文主要比较 3 个模型: RoBER ...

  5. 一文掌握 Kubernetes 证书

    如果你正在自己的环境中运行 Kubernetes,那么了解证书的工作原理以及如何管理它们以确保集群的安全性和完整性至关重要.在本文中,我们将解释什么是 Kubernetes 证书.其重要性,以及如何检 ...

  6. 使用vLLM和ChatGLM3-6b批量推理

    当数据量大的时候,比如百万级别,使用 ChatGLM3-6b 推理的速度是很慢的.发现使用 vLLM 和 ChatGLM3-6b 批量推理极大的提高了推理效率.本文主要通过一个简单的例子进行实践. 1 ...

  7. 【Python】【OpenCV】定位二维码

    相较于BarCode,QRCode有明显的特征区域,也就是左上角.右上角.左下角三个"回"字区域,得益于hierarchy中,父子关系的轮廓是连续的(下标),所以这个时候我们就可以 ...

  8. 直接在*.vue文件(SFC)中使用JSX/TSX渲染函数,真香!

    前言 在日常开发中vue的模版语法在大多数情况都能够满足我们的需求,但是在一些复杂的业务场景中使用模版语法就有些麻烦了.这个时候灵活的JSX/TSX渲染函数就能派上用场了,大多数同学的做法都是将*.v ...

  9. Python中的@abstractmethod

      @abstractmethod 是 Python 中 abc 模块(Abstract Base Classes)提供的一个装饰器,用于声明抽象方法.抽象方法是指在抽象类中声明但没有提供具体实现的方 ...

  10. gitee图床不能用了,心态崩了

    起因 大概上周五晚上吧,想着可以正常下班了.也没啥事,正好可以逛逛自己的小破站,看看有没有小伙伴留言什么的. 然后发现小破站图片显示不出来了... 一开始也没在意,想着可能是Gitee又挂了,可能一会 ...