1. qsort到底是什么?
qsort是C語(yǔ)言庫(kù)函數(shù)里面的一種,包含于#include <stdlib.h>這個(gè)頭文件里面,使用快速排序的方法
2. qsort庫(kù)函數(shù)的功能
qsort英語(yǔ)解析:Quick sort,翻譯就是快速排序,它的內(nèi)部實(shí)現(xiàn)是通過(guò)的快速排序算法來(lái)實(shí)現(xiàn)的。
功能:對(duì)傳入的任何數(shù)據(jù)進(jìn)行排序,使其變成有序數(shù)列。
void qsort(void* base, //指向了待排序數(shù)組的第一個(gè)元素
size_t num, //待排序的元素個(gè)數(shù)
size_t size, //每個(gè)元素的大小,單位是字節(jié)
int (* cmp)(const void*, const void*) //指向一個(gè)函數(shù),這個(gè)函數(shù)可以比較2個(gè)元素的大小
);
qsort是可以排序任意類(lèi)型的數(shù)據(jù)
- 比較2個(gè)整數(shù)的大小,> < ==
- 比較2個(gè)字符串的大小,strcmp
- 比較2個(gè)結(jié)構(gòu)體數(shù)據(jù)(學(xué)生:張三,李四)指定比較的標(biāo)準(zhǔn),拿什么比較?
3. qosrt函數(shù)詳解
在C語(yǔ)言庫(kù)中是這樣定義的:
void qsort (void* base, size_t num, size_t width, int (cmp)(const void, const void* ))
剖析:
返回類(lèi)型void:我們改變的是數(shù)列的排序,實(shí)際只需要進(jìn)行內(nèi)存的操作,所以不需要返回值。
參數(shù)講解:
void*
base:base基本,即表示應(yīng)傳入初始地址,至于為什么是void類(lèi)型,它不知道我們會(huì)傳入什么數(shù)據(jù),而void類(lèi)型就像一個(gè)垃圾桶一樣什么地址都可以仍進(jìn)去,所以只能用void*類(lèi)型。size_t num:num數(shù)量,表示應(yīng)傳入的元素個(gè)數(shù)
size_t width:width寬度,表示應(yīng)傳入的每個(gè)元素占的字節(jié)大小
int (*cmp)(const void *, const void *):
應(yīng)傳入一個(gè)比較函數(shù)地址,用于比較兩個(gè)數(shù)據(jù)的大小,因?yàn)閭魅氲臄?shù)據(jù)類(lèi)型是不確定的,所以我們需要自己定義一個(gè)比較函數(shù)傳到qsort比較函數(shù)里面去,以便它知道怎么樣去比較兩個(gè)數(shù)據(jù)的大小。
4. 冒泡排序的實(shí)現(xiàn)
void bubble_sort(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
//一趟冒泡排序的過(guò)程
int j = 0;
for (j = 0; j < sz-1-i; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
//排序
//使用冒泡排序的算法,來(lái)排序
int sz = sizeof(arr) / sizeof(arr[0]);
//
bubble_sort(arr, sz);
//打印
print_arr(arr, sz);
return 0;
}
5. qsort庫(kù)函數(shù)如何實(shí)現(xiàn)冒泡排序
排成升序的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//qsort函數(shù)的使用者提供這個(gè)函數(shù)
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p1 - *(int*)p2; //排成升序的
}
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
test1()
{
int arr[] = { 3,1,5,2,4,9,8,6,5,7 };
int sz = sizeof(arr) / sizeof(arr[0]);
//使用qsort來(lái)排序整型數(shù)組,這里就要提供一個(gè)比較函數(shù),這個(gè)比較函數(shù)能夠比較2個(gè)整數(shù)的大小
//qsort 默認(rèn)是排成升序的
qsort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
int main()
{
test1();
return 0;
}
排成降序的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//qsort函數(shù)的使用者提供這個(gè)函數(shù)
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p2 - *(int*)p1; //排成降序的
}
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
test1()
{
int arr[] = { 3,1,5,2,4,9,8,6,5,7 };
int sz = sizeof(arr) / sizeof(arr[0]);
//使用qsort來(lái)排序整型數(shù)組,這里就要提供一個(gè)比較函數(shù),這個(gè)比較函數(shù)能夠比較2個(gè)整數(shù)的大小
//qsort 默認(rèn)是排成升序的
qsort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
int main()
{
test1();
return 0;
}
6. qsort庫(kù)函數(shù)排序結(jié)構(gòu)體數(shù)據(jù)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//測(cè)試qsort 排序結(jié)構(gòu)體數(shù)據(jù)
struct Stu
{
char name[20];
int age;
};
//按照年齡來(lái)比較
int cmp_stu_by_age(const void* p1, const void* p2)
{
return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}
int cmp_stu_by_name(const void* p1, const void* p2)
{
return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
void test2()
{
struct Stu s[] = { {"zhangsan", 30}, {"lisi", 25}, {"wangwu", 50} };
int sz = sizeof(s) / sizeof(s[0]);
//測(cè)試按照年齡來(lái)排序
//qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
//測(cè)試按照名字來(lái)排序
qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
test2();
return 0;
}
7. 使用冒泡排序的思想來(lái)實(shí)現(xiàn)類(lèi)似于qsort
模擬一下
但是因?yàn)槲覀儧](méi)有學(xué)習(xí)快速排序的思想
所以我們使用冒泡排序的思想來(lái)實(shí)現(xiàn)類(lèi)似于qsort這個(gè)功能的冒泡排序函數(shù)bubble_sort.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p1 - *(int*)p2;
}
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
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++;
}
}
//假設(shè)排序?yàn)樯?/span>
//希望這個(gè)bubble_sort函數(shù)可以排序任意類(lèi)型的數(shù)據(jù)
void bubble_sort(void* base, size_t num, size_t width, int (*cmp)(const void* p1, const void* p2))
{
//要確定趟數(shù)
size_t i = 0;
for (i = 0; i < num - 1; i++)
{
int flag = 1;//假設(shè)已經(jīng)有序了
//一趟冒泡排序的過(guò)程
size_t j = 0;
for (j = 0; j < num - 1 - i; j++)
{
//兩個(gè)相鄰的元素比較
//arr[j] arr[j+1]
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) //改成小于0就變?yōu)榻敌?/span>
{
//交換
flag = 0;
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
if (flag == 1)
{
break;
}
}
}
void test3()
{
int arr[] = { 3,1,5,2,4,9,8,6,5,7 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
int main()
{
test3();
return 0;
}
圖片流程詳解:
在練習(xí)一下模擬qsort庫(kù)函數(shù)排序結(jié)構(gòu)體數(shù)據(jù),道理相同。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-785953.html
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//測(cè)試qsort 排序結(jié)構(gòu)體數(shù)據(jù)
struct Stu
{
char name[20];
int age;
};
//按照年齡來(lái)比較
int cmp_stu_by_age(const void* p1, const void* p2)
{
return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}
int cmp_stu_by_name(const void* p1, const void* p2)
{
return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
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++;
}
}
//假設(shè)排序?yàn)樯?/span>
//希望這個(gè)bubble_sort函數(shù)可以排序任意類(lèi)型的數(shù)據(jù)
void bubble_sort(void* base, size_t num, size_t width,
int (*cmp)(const void* p1, const void* p2))
{
//要確定趟數(shù)
size_t i = 0;
for (i = 0; i < num - 1; i++)
{
int flag = 1;//假設(shè)已經(jīng)有序了
//一趟冒泡排序的過(guò)程
size_t j = 0;
for (j = 0; j < num - 1 - i; j++)
{
//兩個(gè)相鄰的元素比較
//arr[j] arr[j+1]
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
//交換
flag = 0;
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
if (flag == 1)
{
break;
}
}
}
void test4()
{
struct Stu s[] = { {"zhangsan", 30}, {"lisi", 25}, {"wangwu", 50} };
int sz = sizeof(s) / sizeof(s[0]);
//測(cè)試按照年齡來(lái)排序
//bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_age);
//測(cè)試按照名字來(lái)排序
bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
int main()
{
test4();
return 0;
}
如果這份博客對(duì)大家有幫助,希望各位給恒川一個(gè)免費(fèi)的點(diǎn)贊作為鼓勵(lì),并評(píng)論收藏一下,謝謝大家?。。?br> 制作不易,如果大家有什么疑問(wèn)或給恒川的意見(jiàn),歡迎評(píng)論區(qū)留言。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-785953.html
到了這里,關(guān)于【進(jìn)階C語(yǔ)言】qsort庫(kù)函數(shù)(詳解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!