赞
踩
qsort函数是八大排序算法中的快速排序,能够排序任意数据类型的数组,包括实现整型,浮点型,结构体,字符串等的排序。qsort函数主要通过利用回调函数实现。
回调函数就是一个通过函数指针调用的函数,如果你把函数指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用,用于对该事件或条件进行响应。
头文件:#include<stdio.h>
void qsort(void* base,//要排序的数据的首元素地址
int num,//要排序的数据个数
int width,//元素的字节大小
void(*cmp)(const void* e1, const void* e2));//函数指针-接收比较函数,比较函数需要我们自己实现
关于为什么要使用void*指针:首先要明确void**是无具体类型的指针,可以接受任意类型的地址,而qsort函数可以排序多种类型的数据,所以我们利用空指针接受地址。需要注意的是空指针没有确定的步长大小,所以空指针不能加减整数,不能对空指针进行解引用。
(1)升序
#include<stdio.h> #include<stdlib.h> //整型的比较函数 int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } int main() { int arr[] = { 9,8,7,6,5,4,3,2,1,0 }; int sz = sizeof(arr) / sizeof(arr[0]); //qsort库函数的使用 qsort(arr, sz, sizeof(arr[0]), cmp_int); int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
(2)降序
#include<stdio.h> #include<stdlib.h> int cmp_int(const void* e1, const void* e2) { return *(int*)e2 - *(int*)e1;//后一个元素比前一个元素大,就交换 } int main() { int arr[] = { 0,1,2,3,4,5,6,7,8,9,10 }; 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]); } return 0; }
(1)按年龄排序
#include<stdio.h> #include<stdlib.h> //定义结构体类型 struct Stu { //结构体成员 int age; char name[20]; }; int cmp_stu_by_age(const void* e1, const void* e2) { //需要e1需要括号括起,才能访问到结构体数据 return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age; } int main() { struct Stu s[] = { {30,"lisi"},{20,"wangwu"},{10,"zhangsan"} }; int sz = sizeof(s) / sizeof(s[0]); qsort(s, sz, sizeof(s[0]), cmp_stu_by_age); int i = 0; for (i = 0; i < sz; i++) { printf("%d %s\n", s[i].age, s[i].name); } return 0; }
(2)按名字排序
#include<stdio.h> #include<stdlib.h> struct Stu { int age; char name[20]; }; int cmp_stu_by_name(const void* e1, const void* e2) { //字符串的比较用strcmp return strcmp( ((struct Stu*)e1)->name, ((struct Stu*)e2)->name ); } int main() { struct Stu s[] = { {30,"lisi"},{20,"wangwu"},{10,"zhangsan"} }; int sz = sizeof(s) / sizeof(s[0]); qsort(s, sz, sizeof(s[0]), cmp_stu_by_name); int i = 0; for (i = 0; i < sz; i++) { printf("%d %s\n", s[i].age, s[i].name); } return 0; }
(1)排序整数
#include<stdio.h> //比较函数 int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } //以字节单位交换 void Swap(char* buf1, char* buf2, int width)//以字节为单位交换 { int i = 0; for (i = 0; i < width; i++) { char temp = *buf1; *buf1 = *buf2; *buf2 = temp; buf1++; buf2++; } } void bubble_sort(char* base, int sz, int width, int(*cmp)(int, int)) { int i = 0; int j = 0; int flag = 0; for (i = 0; i < sz - 1; i++) { flag = 1; for (j = 0; j < sz - 1 - i; j++) { //强制类型转换成char*类型 if (cmp_int((char*)base+j*width,(char*)base+(j+1)*width)>0) { Swap((char*)base + j * width, (char*)base + (j + 1)*width, width); flag = 0; } } if (flag == 1) { break; } } } int main() { int arr[] = { 1,3,5,7,9,2,4,6,8,0 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz, sizeof(arr[0]), cmp_int); int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } return 0; }
(2)排序浮点数
#include<stdio.h> float cmp_float(const void* e1, const void* e2) { return *(float*)e1 - *(float*)e2; } void Swap(char* buf1, char* buf2, int width)//以字节为单位交换 { int i = 0; for (i = 0; i < width; i++) { char temp = *buf1; *buf1 = *buf2; *buf2 = temp; buf1++; buf2++; } } void bubble_sort(void* base, int sz, int width, int(*cmp)(void*, void*)) { int i = 0; int j = 0; int flag = 0; for (i = 0; i < sz - 1; i++) { flag = 1; for (j = 0; j < sz - 1 - i; j++) { if (cmp_float((char*)base+j*width,(char*)base+(j+1)*width)>0) { Swap((char*)base + j * width, (char*)base + (j + 1)*width, width); flag = 0; } } if (flag == 1) { break; } } } int main() { float arr[] = { 9.0,8.0,7.0,6.0,5.0,4.0,3.0,1.1,1.0 }; int sz = sizeof(arr) / sizeof(arr[0]); int i = 0; bubble_sort(arr, sz, sizeof(arr[0]), cmp_float); for (i = 0; i < sz; i++) { printf("%.1f ", arr[i]); } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。