網站首頁 編程語言 正文
前言
今天分享一個庫函數
介紹qsort的使用及實現方法
他可以實現不限于整形、浮點型、字符型、自定義等類型的排序
qsort的簡單介紹
? | qsort |
頭文件 | #include <stdlib.h> |
格式 | void qsort(void* base,size_t num,size_t width,int(__cdecl*compare(const void*,const void*)) |
功能 | 實現多類型的快速排序 |
返回值 | 無返回值 |
把格式分解?
void qsort(void* base, size_t num, size_t width, int(* compare)(const void* e1, const void* e2) );
qsort的首參數為待排列數組的首地址
size_t num為某個類型的個數
size_t width為類型的寬度,也就是該類型的大小
int(* compare)(const void* e1, const void* e2)為比較函數的指針,這里是利用函數指針作為參數,實現傳參
這里運用了回調函數的思想
回調函數就是通過函數指針調用的函數,如果把一個函數的指針(地址)當作參數,傳給另一個函數,當這個函數調用所指的函數時,我們就說這是回調函數。
用qsort實現一個整形類型的排序
#include<stdio.h> #include<stdlib.h> int cmp_int(const void* e1, const void* e2) { return (*(int*)e1) - (*(int*)e2); } void test1() { int arr[] = { 1,4,2,6,5,3,7,9,0,8 }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { test1(); return 0; }
用qsort函數實現結構體的排序
#include<stdio.h> #include<stdlib.h> struct Stu { char name[20]; int age; float score; }; int cmp_stu_by_socre(const void* e1, const void* e2) //結構體中的浮點型 { if (((struct Stu*)e1)->score > ((struct Stu*)e2)->score) { return 1; } else if (((struct Stu*)e1)->score < ((struct Stu*)e2)->score) { return -1; } else { return 0; } } 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); } void print_stu(struct Stu arr[], int sz) //打印函數 { int i = 0; for (i = 0; i < sz; i++) { printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); } printf("\n"); } void test4() { struct Stu arr[] = { {"zhangsan",20,87.5f},{"lisi",22,99.0f},{"wangwu", 10, 68.5f} }; //按照成績來排序 int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_socre); print_stu(arr, sz); qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age); print_stu(arr, sz); qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name); print_stu(arr, sz); } int main() { test4(); return 0; }
結構體的成員包括整形,浮點型和字符型
分別從小到大來排列?
cmp函數通過返回值的正負性來實現比較大小,就可以實現下圖的結果
qsort函數的實現
qsort函數在實現的時候,其實跟冒泡排序有一定的聯系
只不過
相對于冒泡排序,它可以排序各類型的數據,下面通過對比來實現其函數的功能
冒泡排序實現整形的排序
void bubble(int arr[],int sz) //冒泡排序實現整形的排序 { int tmp = 0; int i = 0; int j = 0; for (i = 0; i < sz - 1; i++) { for (j=0;j<sz-1;j++) { if (arr[j] > arr[j + 1]) { tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } } }
qsort函數的實現
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++; } } void bubble_sort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2)) { int i = 0; for (i = 0; i < sz - 1; i++) { int j = 0; for (j = 0; j < sz - 1 - i; j++) { //if (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); } } } }
可以看出有兩個地方有差異
首先就是兩個元素比較大小,是通過cmp比較函數實現
當返回值大于零,函數就實現從小到大來排序
當返回值小于零,函數就實現從大到小來排序
當返回值等于零,元素不發生變化
第二個差異就是,實現兩個元素的交換
冒泡排序就是通過引入一個中間變量,達到交換的目的
而qsort函數,通過調用一個函數,通過引入寬度(所占字節的大小),進行字節之間的交換,所以用char類型來實現不同類型的交換,所以首先需要知道排序數組內每一個元素的大小,整形就交換四個字節的空間即可。
原文鏈接:https://z-ming.blog.csdn.net/article/details/122774748
相關推薦
- 2022-09-30 Nginx使用ngx_http_upstream_module實現負載均衡功能示例_nginx
- 2023-06-18 C#Process的OutputDataReceived事件不觸發問題及解決_C#教程
- 2022-07-30 Linux文件管理命令行
- 2022-09-22 Mybaits一級緩存和二級緩存分別是什么,區別是什么?
- 2023-02-27 pandas中concatenate和combine_first的用法詳解_python
- 2023-07-24 前端終止請求的三種方式(ajax、axios)
- 2024-01-11 redis開啟密碼驗證
- 2024-07-18 maven:解決release錯誤:Artifact updating: Repository =‘
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支