API-qsort
排序API的作用就是传入一个一维数组,并且按照给定的规则就地排序
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));
qsort的调用
例如我们对如下数组进行排序
int a [5]={1,2,4,3,5};
就可以怎么写
void qsort(void*base,5,sizeof(int),cmp);
这样就能将该数组变为从一到五的顺序
其中 sizeof(int)就代表了单个数组元素的字节数,5 则代表了数组的大小,总的字节数就是两者的乘积。而 cmp 是一个比较数,是需要我们自己实现的,它决定了数组是递增排序 还是 递减排序,还是其它的排序方式(比如奇数排前面,偶数排后面,等等)接下来,我们来看看 cmp 函数的实现方式。
比较函数
int compar(const void *p1, const void *p2);
如果 compar 返回值小于0,则 p1 所指向元素会被排在 p2 所指向元素的左面
如果 compar 返回值等于0,则 p1 所指向元素与 p2 所指向元素的顺序不确定
如果 compar 返回值大于0,则 p1 所指向元素会被排在 p2 所指向元素的右面
那么如果我们需要写一个递增的排序 可以这样写
int cmp(const void *p1,const void *p2) {
int v1 = *(int*)p1;
int v2 = *(int*)p2;
if (v1>v2) {
return -1;
}else if(v1<v2) {
return 1;
}
return 0;
}
(1)需要和系统给定的函数原型保持一致,由于需要适配任何类型,所以用空指针 void * 做为参数类型
(2) p1 强制转换成数组元素的指针类型,然后再解引用 变成数组元素的值;
(3) p2 强制转换成数组元素的指针类型,然后再解引用 变成数组元素的值;
如果确定数组的数据相减不会超过32位整型,可以简化写法
int cmp(const void *p1, const void *p2) {
return (*(int *)p2) - (*(int *)p1);
}
当然也可以通过交换p1,p2的写法 变为递减
如果要求偶数排前面,奇数排后面 可以用下面的写法
int Qua(int x) {
return x % 2;
}
int cmp(const void *p1, const void *p2) {
return Qua(*(int *)p1) - Qua(*(int *)p2);
}
例题:
给定一个无序数组,求排序后相邻元素的最大差值
int cmp(const void *p1, const void *p2) {
return *(int*)p1 - *(int*)p2;
}
int main(int * nums, numsSize) {
int i = 0; max = 0;
qsort(nums,numsSize,seizeof(int),cmp);
for(i=0;i<numsSize;++i){
if(nums[i]-nums[i-1]>max){
max=nums[i]-nums[i+1];
}
}
return max;
}