资讯专栏INFORMATION COLUMN

qsort函数用法以及如何自己实现

jerry / 2363人阅读

摘要:声明下面是函数的声明。参数指向要排序的数组的第一个元素的指针。数组中每个元素的大小,以字节为单位。返回值该函数不返回任何值。

声明

下面是 qsort() 函数的声明。

</>复制代码

  1. void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))

参数

  • base -- 指向要排序的数组的第一个元素的指针。
  • nitems -- 由 base 指向的数组中元素的个数。
  • size -- 数组中每个元素的大小,以字节为单位。
  • compar -- 用来比较两个元素的函数。

返回值

该函数不返回任何值。

举例如下:

</>复制代码

  1. #include #include int cmp (const void * a, const void * b){ return ( *(int*)a - *(int*)b );}int main(){ int values[] = { 88, 56, 100, 2, 25 }; int sz=sizeof(values)/sizeof(values[0]); qsort(values, sz, sizeof(values[0]), cmp); printf("/n排序之后的列表:/n"); for( n = 0 ; n < sz; n++ ) { printf("%d ", values[n]); } return(0);}

 qsort函数就是多功能版的冒泡排序,让我们在冒泡排序的基础上更改;

冒泡排序参数只需要首地址,元素个数,qsort函数的参数分别要传首地址,元素个数,单位字节数,排序规则(是个函数),相同的是有两层循环,外层循环是一共排多少趟,内层是一趟排列多少对,在原地址排序不要要返回值;

</>复制代码

  1. if (cmp((char*)base + j*width, (char*)base + (j + 1)*width) > 0){ //交换
  2. swap((char*)base + j*width, (char*)base + (j + 1)*width, width);}

 多带带解释一下:想要通用排序函数,参数的类型不能多带带化,所以地址只能用void*来接收;

但是在比较两数大小时,要解引用,void型不能解引用。在知道单位字节的情况下可以强制转化为(char*)加上整数倍个单位字节数,来访问元素;

当内部循环 j=0 时,第一个元素可以表示为(char*)base+j*width

                                第二个元素可以表示为(char*)base+(j+1)*width

当 前者 大于 后者 时要进行交换,交换函数与冒泡函数有所不同;

最后一点:规则排序函数

排列int型,上面有

再举一个例子,排列结构体类型;

</>复制代码

  1. int cmp_stu(const void* e1, const void* e2){
  2. return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name); //先强制转化为结构体类型,再解引用;}struct stu{
  3. char name[20];
  4. int age;};struct stu s[3] = { { "zhangsan", 20 }, { "lisi", 15 }, { "wangwu", 30 } };

当前者大于后者将返回一个正数,与上面判断大于0时交换数据相呼应; 

排列整形源代码如下:

</>复制代码

  1. #include int cmp_int(const void* e1, const void* e2){
  2. return *(int*)e1 - *(int*)e2;}void swap(char* buf1, char*buf2, int width){
  3. for (int i = 0; i < width; i++)
  4. {
  5. char tmp = *buf1;
  6. *buf1 = *buf2;
  7. *buf2 = tmp;
  8. buf1++;
  9. buf2++;
  10. }}void my_qsort(void* base, size_t num, size_t width, int(*cmp)(const void*, const void*)){
  11. //趟数;
  12. for (int i = 0; i < num; i++)
  13. {
  14. //比较对数;
  15. for (int j = 0; j < num - 1 - i; j++)
  16. {
  17. if (cmp((char*)base + j*width, (char*)base + (j + 1)*width) > 0)
  18. {
  19. //交换;
  20. swap((char*)base + j*width, (char*)base + (j + 1)*width,width);
  21. }
  22. }
  23. }}int main(){
  24. int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
  25. int sz = sizeof(arr) / sizeof(arr[0]);
  26. my_qsort(arr, sz, sizeof(arr[0]), cmp_int);
  27. for (int i = 0; i < sz; i++)
  28. {
  29. printf("%d ", arr[i]);
  30. }
  31. printf("/n");}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/119013.html

相关文章

  • qsort()函数详解

    摘要:函数详解函数原型函数的作用及用法函数的参数函数实例排序一个整型数组排序一个结构体用冒泡排序模拟一个函数函数原型函数的作用及用法函数的功能是对数组进行排序,数组有个元素,每个元素大小为可以排序数字,字符,结构体等多种类型 ...

    LiveVideoStack 评论0 收藏0
  • 指针学习进阶

    摘要:让我们来看一下代码,首先我们还是冒泡排序一样,进行了两次循环,第一次代表排序趟数,第二次代表每趟的排序次数。这块的详细介绍在本篇文章稍前的冒泡排序中也有详细介绍。 ...

    oysun 评论0 收藏0
  • C | 指针的相关知识(二)

    摘要:回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。 目录 前言无类型指针结构体指针枚举变量指针函数...

    alin 评论0 收藏0
  • C语言进阶:指针进阶续

    摘要:故使用无具体类型,又称通用类型,即可以接收任意类型的指针,但是无法进行指针运算解引用,整数等。求指针所占字节而不是解引用访问权限大小。数组就是整个数组的大小,数组元素则是数组元素的大小,指针大小都为。 ...

    ingood 评论0 收藏0

发表评论

0条评论

jerry

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<