qsort函数是库函数中的一员,我们先来看看官方文档是怎么写的:
其中qsort的参数void* base是传入一个数组,size_t num 为数组整体大小,size_t size 为单个元素的大小,int (*compar)(const void*,const void*)是需要使用者去完成的一个比较函数
针对这个函数,在不同类型的数组中需要用不同的处理方式,来保证数组中的元素大小不会失真(例如在处理double型的数组时就需要用不同的方式来进行)
比较函数的返回值是;
return value | meaning |
---|---|
<0 |
The element pointed to by p1 goes before the element pointed to by p2 |
0 |
The element pointed to by p1 is equivalent to the element pointed to by p2 |
>0 |
The element pointed to by p1 goes after the element pointed to by p2 |
我们来看一个例子:这是官方文档为我们提供的一个例子:关于对 qsort 的使用
1 /* qsort example */ 2 #include <stdio.h> /* printf */ 3 #include <stdlib.h> /* qsort */ 4 5 int values[] = { 40, 10, 100, 90, 20, 25 }; 6 7 int compare (const void * a, const void * b) 8 { 9 return ( *(int*)a - *(int*)b ); 10 } 11 12 int main () 13 { 14 int n; 15 qsort (values, 6, sizeof(int), compare); 16 for (n=0; n<6; n++) 17 printf ("%d ",values[n]); 18 return 0; 19 }
1.对 int 类型的数组排序
1 //qsort函数 2 #include <stdio.h> 3 #include<stdlib.h> 4 //qsort函数实现int型排序 5 //qosrt函数的使用者得实现一个比较函数 6 int int_cmp(const void * p1, const void * p2) 7 { 8 return (*( int *)p1 - *(int *) p2); 9 } 10 11 int main() 12 { 13 int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 }; 14 qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp); 15 for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) 16 { 17 printf("%d ", arr[i]); 18 } 19 printf(" "); 20 return 0; 21 }
2.对 char 类型的数组排序
1 //qosrt函数实现char型排序 2 #include<stdio.h> 3 #include<stdlib.h> 4 int char_cmp(const void* str1, const void* str2) 5 { 6 return *(char*)str1 - *(char*)str2; 7 } 8 9 int main() 10 { 11 char str[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 }; 12 qsort(str, sizeof(str) / sizeof(str[0]), sizeof(char), char_cmp); 13 for (int i = 0; i < sizeof(str) / sizeof(str[0]); ++i) 14 { 15 printf("%d ", str[i]); 16 } 17 18 return 0; 19 }
3.对 double 类型数组排序(需要特别注意)
1 //qosrt函数实现double型排序 2 #include<stdio.h> 3 #include<stdlib.h> 4 int double_cmp(const void* arr1, const void* arr2) 5 { 6 return *(double*)arr1 > *(double*)arr2 ? 1 : -1; 7 //注意这里是用比较大小的方法,来返回正负 8 } 9 10 int main() 11 { 12 double arr[] = { 1.4, 3.9, 5.4, 5.2, 9, 2, 4, 6, 8, 0 }; 13 qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(double), double_cmp); 14 for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i) 15 { 16 printf("%f ", arr[i]); 17 } 18 19 return 0; 20 }
4.对结构体一级排序
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 typedef struct Student 5 { 6 int x; 7 int y; 8 //按照x从小到大排序,当x相等时按照y从大到小排序 9 }Student; 10 11 Student student[7]; 12 13 int cmp(const void *a, const void *b) 14 { 15 Student* pa1 = (Student*)a; 16 Student* pa2 = (Student*)b; 17 18 return (pa1->x) > (pa2->x) ? 1 : -1; 19 } 20 21 //展示一下对于结构体里赋值的后的结果 22 void Display() 23 { 24 for (int i = 0; i < 7; ++i) 25 { 26 printf("%d ",student[i].x); 27 } 28 } 29 30 int main() 31 { 32 int arr[7] = { 1,3,5,2,6,9,7 }; 33 for (int i = 0; i < 7; ++i) 34 { 35 //将数组arr中的元素赋值给结构体x中 36 student[i].x = arr[i]; 37 } 38 Display(); 39 qsort(student, 7, sizeof(Student), cmp); 40 for (int i = 0; i < 7; ++i) 41 { 42 printf("%d", student[i].x); 43 } 44 45 return 0; 46 }
5.对机构体二级的排序
就对于4中的结构体来说,如果给x赋值,则x中的值都为0,那么就需要来比较y中的数组。
则可以将代码改为下面这样:
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 typedef struct Student 5 { 6 int x; 7 int y; 8 //按照x从小到大排序,当x相等时按照y从大到小排序 9 }Student; 10 11 Student student[7]; 12 13 int cmp(const void *a, const void *b) 14 { 15 Student* pa1 = (Student*)a; 16 Student* pa2 = (Student*)b; 17 18 if (pa1->x != pa2->x) 19 { 20 return (pa1->x) > (pa2->x) ? 1 : -1; 21 } 22 else 23 { 24 return (pa1->y) > (pa2->y) ? 1 : -1; 25 } 26 } 27 28 //展示一下对于结构体里赋值的后的结果 29 void Display() 30 { 31 printf("x="); 32 for (int i = 0; i < 7; ++i) 33 { 34 printf("%d", student[i].x); 35 } 36 printf(" "); 37 printf("y="); 38 for (int i = 0; i < 7; ++i) 39 { 40 printf("%d", student[i].y); 41 } 42 printf(" "); 43 } 44 45 int main() 46 { 47 int arr[7] = { 1,3,5,2,6,9,7 }; 48 for (int i = 0; i < 7; ++i) 49 { 50 //将数组arr中的元素赋值给结构体x中 51 student[i].y = arr[i]; 52 } 53 Display(); 54 printf("排序结构体中的y: "); 55 qsort(student, 7, sizeof(Student), cmp); 56 for (int i = 0; i < 7; ++i) 57 { 58 printf("%d", student[i].y); 59 } 60 61 return 0; 62 }
6.模仿qsort的功能实现一个通用的冒泡排序
1 //用回调函数模拟实现qsort(冒泡排序的方式) 2 3 #include <stdio.h> 4 5 int int_cmp(const void * p1, const void * p2) 6 { 7 return (*(int *)p1 > *(int *)p2); 8 } 9 10 void _swap(void *p1, void * p2, int size) 11 { 12 int i = 0; 13 for (i = 0; i < size; i++) 14 { 15 char tmp = *((char *)p1 + i); 16 *((char *)p1 + i) = *((char *)p2 + i); 17 *((char *)p2 + i) = tmp; 18 } 19 } 20 21 void bubble(void *base, int count, int size, int(*cmp)(void *, void *)) 22 { 23 int i = 0; 24 int j = 0; 25 for (i = 0; i < count - 1; i++) 26 { 27 for (j = 0; j < count - i - 1; j++) 28 { 29 if (cmp((char *)base + j * size, (char *)base + (j + 1)*size) > 0) 30 { 31 _swap((char *)base + j * size, (char *)base + (j + 1)*size, size); 32 } 33 } 34 } 35 } 36 int main() { 37 int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 }; 38 //char *arr[] = {"aaaa","dddd","cccc","bbbb"}; 39 int i = 0; 40 bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp); 41 for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++) 42 { 43 printf( "%d ", arr[i]); 44 } 45 printf(" "); 46 return 0; 47 }