C語言 快速排序——qsort函數的介紹

qsort函數

  • 1. 函數介紹
  • 2. 函數使用
    • 2.1 整型排序
    • 2.2 字符排序
    • 2.3 字符串排序
    • 2.4 結構體排序
  • 3. 用冒泡思想模擬qsort函數

我們以往使用冒泡排序和選擇排序等對數據進行排序時,有可能會遇到搞不清排序次數,運行時間過長等一些問題,并且這些排序方法也只能排序整型數據。

下面我們了介紹一個內置排序函數----qsort函數。它可以比較任何類型的數據

1. 函數介紹

首先qsort是庫函數,使用時要包含頭文件<stdlib.h>

qsort的函數聲明是:

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

其中,4個參數分別是:

  • void* base:指針,指向的是待排序的數組的第一個元素
  • size_t num:是base指向的待排序數組的元素個數
  • size_t size:base指向的待排序數組的元素的大小
  • int (* compar)(const void * p1 ,const void * p2):函數指針,指向的就是兩個函數的比較函數(排序函數名)。

待排序的數組,元素的個數,每個元素的大小都能看懂,不需要解釋。
排序函數名是什么呢?

排序函數就是由qsort函數的使用者自己定義的函數,使用者明確知道要排序的是什么數據,這些數據應該如何比較,所以自行提供兩個元素的比較函數。
這也就是為什么qsort函數能夠排序任何類型的數據。

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

首先來看排序函數的參數,它的參數一定是const void*
const ---- 是為了保證在函數運行的過程中,p1與p2的值不被改變,是一種保護措施。
void* ---- 這是一種泛型指針,可增強函數的普適性。在使用時看要比較的數據類型進行強制轉換。
返回值:若p1>p2,則返回大于0的整數,若p1<p2,則返回小于0的整數,若p1=p2,則返回0。

2. 函數使用

注意:qsort 函數默認排升序!!
如果想排降序,把下面代碼中的p1與p2互換即可!!

2.1 整型排序

#include <stdio.h>
#include <stdlib.h>//使用者自己定義的比較整型的函數
int cmp_int(const void* p1, const void* p2)
{//int* e1 = (int*)p1;//int* e2 = (int*)p2;//if (*e1 > *e1)//	return 1;//else if (*e1 == *e1)//	return 0;//else//	return -1;//上面的代碼可簡化為:return *(int*)p1 - *(int*)p2;
}void print_int(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}void test1()
{int arr[] = { 5,4,8,9,6,3,2,1 };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_int);print_int(arr, sz);}int main()
{test1();return 0;
}

2.2 字符排序

#include <stdio.h>
#include <stdlib.h>int cmp_char(const void* p1, const void* p2)
{return *(char*)p1 - *(char*)p2;
}void Print_char(char arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%c ", arr[i]);}printf("\n");
}void test2()
{char arr[] = { 'd','r','a','w'};int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_char);Print_char(arr, sz)
}int main()
{test2();return 0;
}

2.3 字符串排序

#include <stdio.h>
#include <stdlib.h>int cmp_chars(const void* p1, const void* p2)
{return (*(char*)p1-*(char*)p2);
}void print_char(char arr[][20], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%s\n", arr[i]);}
}void test3()
{char arr[5][20] = { "hello world","apple","banana" };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_char);print_chars(arr, sz);
}int main()
{test3();return 0;
}

2.4 結構體排序

1.按名字排序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct Stu
{char name[20];int age;
};void print_struct(struct Stu* arr, int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%s %d\n", arr[i].name, arr[i].age);}
}int cmp_name(const void* p1, const void* p2)
{//比較兩個字符串,用strcmp函數return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}void test4()
{struct Stu arr[3] = { {"zhangsan",24},{"lisi",18},{"wangwu",49} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_name);print_struct(arr, sz);
}int main()
{test4();return 0;
}
  1. 按年齡排序
#include <stdio.h>
#include <stdlib.h>struct Stu
{char name[20];int age;
};void print_struct(struct Stu* arr, int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%s %d\n", arr[i].name, arr[i].age);}
}int cmp_age(const void* p1, const void* p2)
{return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}void test5()
{struct Stu arr[3] = { {"zhangsan",24},{"lisi",18},{"wangwu",49} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_age);print_struct(arr, sz);int main()
{test5();return 0;
}

3. 用冒泡思想模擬qsort函數

//用冒泡思想模擬實現qsort函數
void Swap(char* buf1, char* buf2, size_t width)
{assert(buf1 && buf2);int i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}}void my_qsort(void* base, size_t sz, size_t width, int (*cmp)(const void* p1, const void* p2))
{趟數int i = 0;for (i = 0; i < sz - 1; i++){每趟兩兩之間的比較int j = 0;for (j = 0; j < sz - 1 - i; j++){if (cmp((char*)base + j * width ,(char*)base + (j + 1) * width) > 0){Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}}}
}void Print_arr(int arr[], int sz)
{int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");
}int cmp_int(const void* p1, const void* p2)
{return *(int*)p1 - *(int*)p2;
}void test1()
{int arr[] = { 2,5,6,9,8,7,4,1 };int sz = sizeof(arr) / sizeof(arr[0]);my_qsort(arr, sz, sizeof(arr[0]), cmp_int);Print_arr(arr, sz);
}int main()
{test1();//排序整型return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717102.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717102.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717102.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

aop監控spring cloud接口超時,并記錄到數據庫

引入pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0…

寶塔面板安裝各種組件以及部署應用服務

在linux服務器安裝寶塔面板 一、從寶塔官網下載exe安裝包&#xff0c;安裝命令從寶塔官網&#xff08;https://www.bt.cn/&#xff09;獲取 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh二、安…

自動駕駛加速落地,激光雷達放量可期(上)

1 激光雷達應用廣泛&#xff0c;汽車有望成最大催化 激光雷達&#xff08;LiDAR&#xff09;是一種主動遙感技術&#xff0c;通過測定傳感器發出的激光在傳感器與目標物體之間的傳播距離&#xff0c;來分析目標地物表面的反射能量大小、反射波譜的幅度、頻率和相位等信息&#…

Vue項目如何進行優化?

Vue項目優化 1.移除控制臺打印2.壓縮圖片3.CDN加速 1.移除控制臺打印 可以使用插件自動去除&#xff0c;插件包括babel-plugin-transform-remove-console、uglifyjs-webpack-plugin、terser-webpack-plugin。最后選擇了terser-webpack-plugin&#xff0c;腳手架vue-cli用這個插…

一文掃盲:訂單管理系統,訂單是公司生命線。

hello&#xff0c;我是貝格前端工場&#xff0c;本期給大家分享訂單管理系統的知識點&#xff0c;歡迎老鐵們點贊、關注&#xff0c;如有需求可以私信我們。 一、什么是訂單管理系統 單管理系統是一種用于管理和處理訂單的軟件系統。它通常用于企業、電子商務平臺、零售店等需…

高并發高可用--反向代理與負載均衡

高并發高可用架構是指能夠應對大量并發請求并保持高度可用的系統架構。為了實現這一目標&#xff0c;通常會采用一系列技術和策略&#xff0c;包括負載均衡、緩存、分布式系統、冗余部署、容錯處理等。 以下是一些構建高并發高可用架構的關鍵要點&#xff1a; 負載均衡&#…

GEE高階應用python wxee 和eemont——MODIS 中生成NDVI 數據的月度時序影像

結合 wxee 和 eemont eemont概述 谷歌地球引擎是一種基于云的服務,用于矢量和柵格數據的地理空間處理。地球引擎平臺擁有 JavaScript 和 Python API,可使用不同方法處理地理空間對象。谷歌地球引擎還提供了一個巨大的 PETABYTE 級柵格和矢量數據目錄,用戶可以在線處理這些…

技術小知識:面向對象和過程的區別 ⑤

一、思想區別 面相對象&#xff1a;始終把所有事情思考歸類、抽離封裝成對象來調用完成。 面向過程&#xff1a;直接平鋪展開按順序執行完成任務。 面向對象多了很多對象的創建、使用&#xff0c;銷毀的過程資源消耗。是一種模塊化編程思想。 https://www.cnblogs.com/kuangmen…

網絡爬蟲彈幕

1.分析網頁&#xff0c;獲取代碼&#xff0c;提取時間 想要提取出彈幕所在的節點&#xff0c;我們要使用 Beautiful Soup 解析模塊&#xff0c;需要從 bs4 中導入 BeautifulSoup 模塊 創建一個 BeautifulSoup 對象&#xff0c;傳入變量 xml 和解析器 lxml&#xff0c;將該對象賦…

Java自學day5

流程控制語句 流程控制語句:通過一些語句,控制程序的執行流程 順序結構 順序結構語句是Java程序默認的執行流程,按照代碼的先后順序,從上到下依次執行! package orderdemo;public class OrderDemo {public static void main(String[] args) {System.out.println("…

2.2 mul、div、and、or乘除指令及所有寄存器英文名

匯編語言 1. mul乘指令 兩個相乘的數&#xff0c;要么都是8位&#xff0c;要么都是16位 兩個8位數相乘 一個默認放在al中&#xff0c;另一個放在8位reg或內存字節單元中8位乘法&#xff0c;結果默認放在ax中例如&#xff1a;計算100*10 100和10小于255&#xff0c;可以做8位…

一(四)班課表

第二學期 課節時間星期一星期二星期三星期四星期五上午18:20-9:00數學數學數學京劇語文29:10-9:50勞動音樂語文語文音樂310:30-11:10語文語文美術道德與法治數學思維411:20-12:00科學輪滑美術體育英語下午513:20-14:00數學實踐活動音樂欣賞語文英語語文拓展614:10-14:50體育英語…

信息系統安全與對抗-作業2

目錄 1、使用自己姓名拼音創建一個賬戶&#xff0c; 并使用命令和圖形化查看 2、使用自己拼音打頭字母創建一個隱藏賬戶 &#xff0c;并使用命令和圖形化查看 3、使用命令啟動 telnet 服務 4、使用命令打開防火墻 23 端口 5、熟悉LINUX系統&#xff0c;使用命令行創建用戶…

Spring Cloud Nacos集成Seata2.0 AT模式

Spring Cloud Nacos集成Seata2.0 AT模式 以CentOS 7為例&#xff0c;介紹Spring Cloud Nacos集成Seata2.0 AT模式的流程。分成兩個步驟&#xff1a;1.安裝配置seata-server、2.項目集成seata-client 一、下載seata-server安裝包 根據自己的操作系統選擇要下載的安裝包格式&a…

2023年第十四屆藍橋杯大賽軟件類省賽C/C++大學A組真題

2023年第十四屆藍橋杯大賽軟件類省賽C/C大學A組部分真題和題解分享 文章目錄 藍橋杯2023年第十四屆省賽真題-平方差思路題解 藍橋杯2023年第十四屆省賽真題-更小的數思路題解 藍橋杯2023年第十四屆省賽真題-顏色平衡樹思路題解 藍橋杯2023年第十四屆省賽真題-買瓜思路題解 藍橋…

05-Linux部署MySQL

Linux部署MySQL 在今后的使用過程中&#xff0c;需要頻繁使用Linux系統&#xff0c;所以在Linux上安裝軟是必不可少的操作 。 前置要求 需要學習前四章知識&#xff0c;初識Linux、Linux基礎命令、Linux權限管理、Linux高階技巧這4個章節。需要開啟多態虛擬機&#xff0c;電…

KubeSphere簡介,功能介紹,優勢,架構說明及應用場景

KubeSphere 是在目前主流容器調度平臺 Kubernetes 之上構建的企業級分布式多租戶容器平臺&#xff0c;提供簡單易用的操作界面以及向導式操作方式&#xff0c;在降低用戶使用容器調度平臺學習成本的同時&#xff0c;極大減輕開發、測試、運維的日常工作的復雜度&#xff0c;旨…

每日一題 — 快樂數

202. 快樂數 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 可以借用判斷鏈表是否有環的思想&#xff1a; 定義快慢指針&#xff08;兩個變量賦值就行&#xff09;快指針走兩次&#xff0c;慢指針走一次快慢指針相遇&#xff0c;看是不是等于一 public int bitSum(…

c++之stack(棧)與queue(隊列)的使用與簡單實現

文章目錄 說明stack與 queuepushpop()刪除top()查頭queue的back()查尾size()長度empty()判空 說明 棧的簡單實現很簡單&#xff0c;但是有一個強制要求&#xff0c;傳過來的類模版中&#xff0c;必須包含尾插頭刪等操作 隊列同理 他們兩個叫空間適配器,不同于其他stl的類 stack…

緩存相關問題:雪崩、穿透、預熱、更新、降級的深度解析

??祝屏幕前的小伙伴們每天都有好運相伴左右?? &#x1f388;&#x1f388;作者主頁&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; 目錄 引言 1. 緩存雪崩 1.1 問題描述 1.2 解決方案 1.2.1 加鎖防止并發重建緩存 2. 緩存穿透 2.1 問題描述 2.2 解決方案 2.2.1 …