文章目录
- 一.qsort函数的使用
- 1.qsort函数定义:
- 2.使用
- 二.qsort函数的模拟实现
一.qsort函数的使用
1.qsort函数定义:
qsort函数实现的功能为:对一组数据进行排序。
表现形式:
void qsort(void *base, size_t num, size_t size, int (*compar)(const void *, const void *);
1.该函数的返回值为空(void)。
2.void *base 任意类型需要排序数据的起始地址。
3.size_num 需要排序数据的元素个数。
4.int (*compar)(const void*, const void* )返回值为int的比较函数指针,参数为任意类型需要比较数据两元素的地址。
注意:int (*compar)(const void*, const void* )需要用户来实现编写。
当比较函数两参数前大后小,返回值大于0.前小后大返回值小于0,两种相等返回值等于0。这样就实现了升序排序。
前大后小,返回值小于0。前小后大返回值大于0,两种相等返回值等于0。这样就实现了降序排序。
2.使用
对一字符串数组进行排序。(比较原理:对两字符串对应每一元素ASSCLL码逐个比较,大的,整个字符串就大)
主函数:
int main(){char *arr[] = { "caic", "asdda", "asdc", "5463" };int num = sizeof(arr) / sizeof(arr[0]);show(arr, num);qsort(arr, num, sizeof(char *), cmp_char);printf("\n");show(arr, num);return 0;
}
比较函数:(注意强转类型)
int cmp_char(const void *xp,const void *yp){char *_xp = *(char **)xp;//由于函数形参为void *分辨不出什么类型。这里用户知道类型,强转成要排序数传进来的类型。char *_yp = *(char **)yp;//一层解引用为字符串首地址。return strcmp(_xp, _yp);//比较用字符串首地址比较
}
为什么强转成char ** 主函数的字符数组中里面的元素是char *的,数组传参降维,降维成数组元素类型的指针。
显示函数:
void show(char **arr, int num){int i = 0;for (; i < num; i++){printf("%s ", arr[i]);//字符串用首地址来输出}
}
输出:
二.qsort函数的模拟实现
用冒泡排序举例实现:
分析:排序的基本功能要实现数据的比较,然后交换。
主函数:
int main()
{int arr[] = { 321, 4, -8, 564, 88, -44, -63, 55 };int num = sizeof(arr) / sizeof(arr[0]);Show(arr, num);My_qsort(arr,num,sizeof(int),Cmp);//要实现的qsort函数printf("\n");Show(arr, num);return 0;
}
My_qsort()函数:
void My_qsort(void *arr, int num, int size, int(*Cmp)())
{char *p = (char *)arr;//强转成char *,按一字节为步进。int j = 0;for (; j < num - 1; j++){ //第一层循环比较轮数int i = 0;for (; i < num - 1 - j; i++){ //比较次数if (Cmp((p + i*size), (p + (i + 1)*size))>0){Swap((p + i*size), (p + (i + 1)*size));}}}
}
为什么将arr强转成char *,传进来的数组不知道什么类型的,强转成char *后,跨度为字节,p + i*size就实现了指向第i个元素的首地址。
比较函数:
int Cmp(const void *xp, const void *yp){int *_xp = (int *)xp;//强转成需要排序数据元素类型的地址int *_yp = (int *)yp;if (*_xp > *_yp){return 1;}else if (*_xp < *_yp){return -1;}else{return 0;}
}
交换函数:
void Swap(void* _xp,void *_yp,int size){char *xp = (char *)_xp;char *yp = (char *)_yp;for (int i = 0; i < size; i++){*xp ^= *yp;*yp ^= *xp;*xp ^= *yp;//不建立临时变量方式交换两数xp++;yp++;}//int temp = *xp;//*xp = *yp;//*yp = temp;}
一字节一字节的交换
交换用两种方法:一种用临时变量,第二种用异或。
显示函数:
void Show(int *arr,int num)
{for (int i = 0; i < num; i++){printf("%d ", arr[i]);}
}