??博客主頁(yè): 小羊失眠啦
??系列專(zhuān)欄: C語(yǔ)言
???每日語(yǔ)錄:沒(méi)有退路,只能讓自己變得強(qiáng)大
??感謝大家點(diǎn)贊??收藏?評(píng)論??
前言
在上篇指針進(jìn)階中,我們對(duì)函數(shù)指針、函數(shù)指針數(shù)組、函數(shù)指針數(shù)組指針以及回調(diào)函數(shù)有了一定的了解,文章末尾簡(jiǎn)單的對(duì)qsort函數(shù)進(jìn)行了展示,今天我們主要以qsort函數(shù)用冒泡排序的模擬實(shí)現(xiàn)以及各種類(lèi)型的排序,后面針對(duì)指針和數(shù)組一些細(xì)節(jié)上的講解~
一、qsort函數(shù)介紹
qsort是一個(gè)庫(kù)函數(shù),快速排序的方法來(lái)實(shí)現(xiàn)的, 頭文件是<stdlib.h>
qsort庫(kù)函數(shù):
void qsort( void *base, size_t num, size_t size, int (*compare )(const void *, const void *) );
傳入的參數(shù),一個(gè)是指針,一個(gè)整形,一個(gè)整形,一個(gè)函數(shù)指針;
base 數(shù)組首元素(就是數(shù)組名),num數(shù)組里有多少個(gè)元素,size每個(gè)元素的大?。▎挝皇亲止?jié)),compare指向數(shù)組中比較方式的函數(shù)指針;
功能介紹:
使用函數(shù)確定順序,對(duì)指向的數(shù)組的元素進(jìn)行排序,每個(gè)元素的長(zhǎng)度以字節(jié)為單位。
此函數(shù)使用的排序算法通過(guò)調(diào)用指定的函數(shù)(要自己定義元素比較方式函數(shù)傳給qsort)并將指向元素的指針作為參數(shù)來(lái)比較元素.
該函數(shù)不返回任何值,而是通過(guò)按定義重新排序數(shù)組元素來(lái)修改指向的數(shù)組的內(nèi)容。
二、qsort函數(shù)的應(yīng)用
由于使用qsort函數(shù)時(shí),并不知道要排序的元素是什么類(lèi)型,這時(shí)需要寫(xiě)一個(gè)compare函數(shù),并對(duì)立面的參數(shù)強(qiáng)制類(lèi)型轉(zhuǎn)化
2.1 整型數(shù)組排序
#include<stdio.h>
#include<stdlib.h>
void Print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int com_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
int main()
{
int arr[] = { 1,3,7,5,8,9,0,2,4,6 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), com_int);
Print(arr, sz);
return 0;
}
運(yùn)行結(jié)果:
0 1 2 3 4 5 6 7 8 9
2.2 浮點(diǎn)型數(shù)組排序
#include <stdio.h>
#include <stdlib.h>
void Print(double arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%2.2lf ", arr[i]);
}
}
int com_double(const void* e1, const void* e2)
{
return *(double*)e1 - *(double*)e2;
}
int main()
{
double arr[6] = { 8.26, 65.5, 73.53, 43.45, 95.3, 19.5 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), com_double);
Print(arr, sz);
return 0;
}
運(yùn)行結(jié)果:
8.26 19.50 43.45 65.50 73.53 95.30
2.3 字符型排序
#include <stdio.h>
#include <stdlib.h>
void Print(char arr[],int sz)
{
for (int i = 0; i < sz; i++)
printf("%c ", arr[i]);
}
int char_sort(const void* e1, const void* e2)
{
return (*(char*)e1) - (*(char*)e2);
}
int main()
{
char arr[10] = { 'd','g','b','a','e','i','h','c','j','f' };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), char_sort);
Print(arr, sz);
return 0;
}
運(yùn)行結(jié)果:
a b c d e f g h i j
2.4 結(jié)構(gòu)體數(shù)組排序
#include <stdio.h>
#include <stdlib.h>
typedef struct student
{
char name[15];
int age;
float score;
}S;
void Print(struct student* stu,int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%-12s %-5d %-5.2fm\n", stu[i].name, stu[i].age, stu[i].score);
}
}
int com_age(const void* e1, const void* e2)
{
return (((S*)e1)->age - ((S*)e2)->age);
}
int com_score(const void* e1, const void* e2)
{
return ((S*)e1)->score - ((S*)e2)->score;
}
int com_name(const void* e1, const void* e2)
{
return strcmp(((S*)e1)->name, ((S*)e2)->name);
}
int main()
{
S stu[5] = { {"chu jie niu",20,1.73f},
{"xiao wang",19,1.68f},
{"qing niao",21,1.59f},
{"wao shu li",16,1.83f},
{"peng hu wan",15,1.81f} };
int sz = sizeof(stu) / sizeof(stu[0]), input = 0;
qsort(stu, sz, sizeof(stu[0]), com_age);
printf("姓名 年齡 身高\(yùn)n");
Print(stu, sz);
return 0;
}
運(yùn)行結(jié)果:
姓名 年齡 身高
peng hu wan 15 1.81 m
wao shu li 16 1.83 m
xiao wang 19 1.68 m
chu jie niu 20 1.73 m
qing niao 21 1.59 m
三、qsort模擬實(shí)現(xiàn)(冒泡排序)
3.1 冒泡排序
#include <stdio.h>
void Print(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
void bubble_sort(int arr[],int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = { 5,3,7,6,1,8,9,2,4,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr,sz);
Print(arr, sz);
return 0;
}
3.2 qsort模擬實(shí)現(xiàn)
第一步:冒泡函數(shù)的參數(shù)
首先要修改的是冒泡排序函數(shù)的參數(shù)void bubble_sort(void* arr,size_t num,size_t width,int(*compare)(const void*,const void*))
需要注意的是qsort函數(shù)事先是不知道傳過(guò)來(lái)的數(shù)組是什么類(lèi)型,所以都先用void*接受
第二步:比較元素的方法
在對(duì)兩元素比較時(shí),事先是不知道類(lèi)型的
- 要先將arr強(qiáng)制類(lèi)型轉(zhuǎn)化為char*,因?yàn)橐粋€(gè)字節(jié)是類(lèi)型的最小單位,這時(shí)候就需要用到width了
- 元素的比較方式不再是單一的相減,這里用到自定義函數(shù),元素的比較方式函數(shù)
if(cmp((char*)arr+jwidth),(char)arr+(j+1)*width)>0)
第三步:交換函數(shù)
修改為char*類(lèi)型進(jìn)行交換
swap(char* e1, char* e2, int width)
{
int i = 0;
char p = 0;
for (i = 0; i < width; i++)
{
p = *(e1 + i);
*(e1 + i) = *(e2 + i);
*(e2 + i) = p;
}
}
注意:void*可以接受任何類(lèi)型的變量,但是并不能直接使用,要強(qiáng)制類(lèi)型轉(zhuǎn)化為對(duì)應(yīng)類(lèi)型使用
代碼展示:
#include <stdio.h>
void Print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
void swap(char* e1, char* e2, int width)
{
int i = 0;
char p = 0;
for (i = 0; i < width; i++)
{
p = *(e1 + i);
*(e1 + i) = *(e2 + i);
*(e2 + i) = p;
}
}
void bubble_sort(void* base, int sz, int width, int (*cmp)(const void* e1, const void* e2))
{
int i = 0;
int j = 0;
for (i = 0; i < sz; i++)
{
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);//一個(gè)字節(jié)一個(gè)字節(jié)的交換
}
}
}
}
int com_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
int main()
{
int arr[] = { 1, 3, 6, 2, 0, 9, 4, 8, 5, 7 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), com_int);
Print(arr, sz);
return 0;
}
qsort函數(shù)用冒泡排序的模擬實(shí)現(xiàn)就講到這里,指針的進(jìn)階也到此結(jié)束了,接下來(lái)對(duì)指針和數(shù)組一些細(xì)節(jié)上的補(bǔ)充到時(shí)候會(huì)在文章見(jiàn)分曉,歡迎大家互三,一起交流,互相學(xué)習(xí)~~文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-731926.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-731926.html
到了這里,關(guān)于『C語(yǔ)言進(jìn)階』qsort函數(shù)及模擬實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!