【C语言】“qsort函数详解”与“使用冒泡思想模拟使用qsort”

news/2024/11/24 13:37:11/

✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦!!✨✨✨✨

文章目录

    • ✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦!!✨✨✨✨
  • qsort的介绍:
  • 一、qsort函数的使用✨
        • 比较int类型数据
        • 比较字符型数据
        • 比较结构体数据
  • 冒泡思想模拟实现qsort函数
    • 完结

qsort的介绍:

  1. qsort ()函数是 C 库中实现的快速排序算法,包含在 stdlib.h 头文件中
  2. 此函数需要四个参数void qsort(void* *base, size_t nitems, size_t size, int (compar)(const void * , const void))
  • char* base —— 指向要排序的数组首元素地址的指针
  • size_t nitems —— 要排序数组的元素个数
  • size_t size —— 数组每个元素大的小 (有非常重要的作用)
  • int compar(const void *,const void *) —— 由使用者提供的一个比较两个元素的函数
    • 有两个参数,如果参数1大于参数2返回>0的数
    • 参数1等于参数2返回0
    • 参数1小于参数2返回<0的数
    • 使用void*当作参数类型是因为此函数是一个回调函数,我们并不知道使用函数的人要比较哪两种数据,所有把参数设置成void *让使用者可以比较任意一种数据。(详细见下面配上代码分解:使用冒牌排序思想模拟实现qsort)

3.此函数无返回值

一、qsort函数的使用✨

  • 比较int类型数据

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void *arr1,const void *arr2)//提供按照int比较函数,如果参数1大于参数2返回>0的数,参数1等于参数2返回0,参数1小于参数2返回<0的数
{return *(int *)arr1 - *(int*)arr2;
}
int main()
{int arr[10] = { 4,3,5,6,7,8,1,2,9,0 };int sz = sizeof(arr) / sizeof(arr[0]);int width = sizeof(arr[0]);qsort(arr, sz, width, cmp_int);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);   //0 1 2 3 4 5 6 7 8 9 }printf("\n");
}
  • 比较字符型数据

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp_char(const void* str1,const void* str2)			//提供按照字符比较函数,如果参数1大于参数2返回>0的数,参数1等于参数2返回0,参数1小于参数2返回<0的数
{return *(char*)str1 - *(char*)str2;
}
int main()
{char str[10] = { 'g','c','b','d','f','e','a' };int len = strlen(str);int width2 =  sizeof(str[0]);qsort(str, len, width2, cmp_char);printf("%s", str);  			//abcdefgprintf("\n");
}
  • 比较结构体数据

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct a 
{char name[10];int age;
};int cmp_stru_a_name(const void * arr3,const void *arr4)		//按照name排序比较方法
{return strcmp(((struct a*)arr3)->name ,((struct a*)arr4)->name);
}int cmp_stru_a_age(const void* arr1, const void* arr2)		//按照age排序比较方法
{return ((struct a*)arr1)->age - ((struct a*)arr2)->age;
}
int main()
{struct a arr2[] = { {"baobao",2} ,{"aoligei",4}{"caomei",3}};int sz2 = sizeof(arr2)/sizeof(arr2[0]);int width3 = sizeof(arr2[0]);qsort(arr2, sz2, width3, cmp_stru_a_name);		//按照结构体中name排序for (int i = 0; i < sz2; i++){printf("%s ", arr2[i].name);    printf("%d ", arr2[i].age);}printf("\n");					//aoligei 4 baobao 2 caomei 3qsort(arr2, sz2, width3, cmp_stru_a_age);		//按照结构体中age排序for (int i = 0; i < sz2; i++){printf("%s ", arr2[i].name);printf("%d ", arr2[i].age);}								//baobao 2 caomei 3 aoligei 4
}

冒泡思想模拟实现qsort函数

qsort底层使用的是快速排序,我们使用冒泡排序思想模拟实现效果与qsort相同的函数

冒泡排序:每次把最大的一个数字交换到最后面


void swap(char* arr1, char* arr2,int width)
{for (int i = 0; i < width; i++){char* temp = *arr1;*arr1 = *arr2;*arr2 = temp;arr1++;arr2++;}
}
int cmp_int(const void* arr1, const void* arr2)		//提供比较函数
{return *(int*)arr1 - *(int*)arr2;		
}void  bubble_sort(void *base,size_t sz,size_t width,int (*cmp)(const void*,const void*))
{for (int i = 0; i < sz - 1; i++){for (int j = 0; j < sz - i - 1; j++){if (cmp((char*)base+j*width,(char*)base+(j+1)*width)>0)	//由于设计bubble_sort函数的时候我们还不知道使用者想比较什么类型的数据,所有可以把base强制转换成字符型指针再乘上元素宽度进行比较,使得无论传入的是什么类型的数据都可以比较。{swap((char*)base+j*width,(char*)base+(j+1)*width,width);//使用swap交换的时候也是如此,我们设计bubble_sort函数的时候不知道要对多少个字节进行交换,所以用把base强转成char*和宽度一起传入swap中,一个字节一个字节的进行交换------## }}}
}
int main()
{int arr[10] = { 3,1,2,4,5,9,7,6,8,0 };int sz = sizeof(arr) / sizeof(arr[0]);int width = sizeof(arr[0]);bubble_sort(arr, sz, width, cmp_int);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);		//打印结果:0 1 2 3 4 5 6 7 8 9}
}

由于设计bubble_sort函数的时候我们还不知道使用者想比较什么类型的数据,所有可以把base强制转换成字符型指针再乘上元素宽度进行比较,使得无论传入的是什么类型的数据都可以比较。

使用swap交换的时候也是如此,我们设计bubble_sort函数的时候不知道要对多少个字节进行交换,所以用把base强转成char*和宽度一起传入swap中,一个字节一个字节的进行交换
拿int类型举例
在这里插入图片描述


完结

创作不易,还请各位小伙伴多多点赞👍关注✨收藏⭐

请添加图片描述


http://www.ppmy.cn/news/28749.html

相关文章

华为OD机试 - 回文字符串(Java JS Python)

题目描述 如果一个字符串正读和反渎都一样(大小写敏感),则称它为一个「回文串」,例如: leVel是一个「回文串」,因为它的正读和反读都是leVel;同理a也是「回文串」art不是一个「回文串」,因为它的反读tra与正读不同Level不是一个「回文串」,因为它的反读leveL与正读不…

【MySQL之SQL语法篇】系统学习MySQL,从应用SQL语法到底层知识讲解,这将是你见过最完成的知识体系

文章目录一、数据管理技术的三个阶段二、SQL语句学习1. DCL数据控制语言1.1 创建用户1.2 修改用户名1.3 修改密码1.4 删除用户1.5 授权1.6 查看权限1.7 回收权限2. DDL数据定义语言2.1 操作数据库2.2 操作数据表2.3 操作数据3. DQL数据查询语言基本语法3.1 单表查询3.1.1选择表…

XXL-JOB

XXL-JOB介绍 XXL-JOB是一个轻量级分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 官网&#xff1a;https://www.xuxueli.com/xxl-job/ 文档&#xff1a;分布式任务调度…

【面试题】当面试官问 Vue2与Vue3的区别,你该怎么回答?

大厂面试题分享 面试题库后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库被问到 《vue2 与 vue3 的区别》应该怎么回答Vue 内部根据功能可以被分为三个大的模块&#xff1a;响应性 reactivite、运行时 runtime、编辑器…

不是,到底有多少种图片懒加载方式?

一、也是我最开始了解到的 js方法&#xff0c;利用滚动事件&#xff0c;判断当时的图片位置是否在可视框内&#xff0c;然后进行渲染。 弊端&#xff1a;代码冗杂&#xff0c;你还要去监听页面的滚动事件&#xff0c;这本身就是一个不建议监听的事件&#xff0c;即便是我们做了…

加密算法---RSA 非对称加密原理及使用

加密算法---RSA 非对称加密原理及使用一 非对称加密原理介绍二 加密解密测试2.1 加密解密工具类2.2 测试一 非对称加密原理介绍 非对称加密算法中&#xff0c;有两个密钥&#xff1a;公钥和私钥。它们是一对&#xff0c;如果用公钥进行加密&#xff0c;只有用对应的私钥才能解…

DLO-SLAM代码阅读

文章目录DLO-SLAM点评代码解析OdomNode代码结构主函数 main激光回调函数 icpCB初始化 initializeDLO重力对齐 gravityAlign点云预处理 preprocessPoints关键帧指标 computeMetrics设定关键帧阈值setAdaptiveParams初始化目标数据 initializeInputTarget设置源数据 setInputSour…

高通平台开发系列讲解(Sensor篇)Gsensor基础知识

文章目录 一、什么是SENSOR?二、Sensor的分类及作用三、Gsensor的工作原理及介绍3.1、常见Gsensor3.2、Gsensor的特性沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇文章将介绍 Sensor 基础 一、什么是SENSOR? 传感器(英文名称:sensor )是一种检测装置,能感…