• 用qsort函数来模拟实现全类型的冒泡排序


    目录

    1.冒泡排序

    2.qsort函数的认识 

    3.qsort函数的实现

    4.模拟实现全类型冒泡排序

    参数设置:

     接收参数:

    ​编辑 编写cmp函数中的参数:

    交换顺序:

    5.整体展示

    1.冒泡排序

    算法思想
    比较相邻的元素。如果第一个比第二个大,就交换他们两个。
    对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

     

    冒泡排序优点: 简单,通俗易懂

           缺点:效率不高 (如果一个数组有n个数,那么排序完成后需要比较n*(n-1)/2次)  并且一般适用于整形 如果是结构体类型,浮点型类型或者其他类型,就会很麻烦 

    2.qsort函数的认识 

     推荐一个网站 :cplusplus.com  

    如果有不认识或不知如何使用的函数,可以使用改网站查询

     这个函数专门用于排序 并且它可以适用于多种类型

    qsort()函数:快速排序的函数  -引用stdlib.h头文件

     

    参数说明

     void qsort ( 

          void* base,     //要排序的目标数组
          size_t num,     //待排序的元素个数
          size_t width,    //待排序单个元素的大小
          int(*cmp)(const void* e1, const void* e2)

    );  // cmp为函数指针,用来比较e1和e2中俩个元素的大小 需要自己结合元素类型编写

     

    3.qsort函数的实现

     接下来我们来实现这个函数

    步骤少,比较简单,这里就不打印了,调试一下看一下结果

     

     主要难点在于qsort函数中的第四个参数 那个是一个函数指针 我们需要自己根据不同的类型来制定这个函数 

     为什么用void*接收  

     void*:无具体类型的指针   它能够接收任意类型的地址 所以不管是什么类型的地址,我们可以用一个通用的void*接收

    但是不能直接对e1和e2进行解引用操作,现在他们现在还是viod*类型 所以必须得强制转化成指针自己的类型  

    比如现在float型类型 我们应该写成  return *(float*e1)-*(float*e2).....

    例如:现在我排序一个结构体类型的数据,

     

     

    这里是按年龄排序,如果按名字排序也是一样的 但是名字排序因为排序的字符,得借助一个函数strcmp函数 字符是不能通过加减排序的

     strcmp刚刚好比较俩个字符的大小

     

    快速排序可以排序所有的类型,接下来我们将用qsort函数的方法来实现全类型的冒泡排序

    4.模拟实现全类型冒泡排序

     

    首先这只是一个最普通的冒泡排序,我们需要对于原冒泡排序进行改造,按qsort函数的方式进行增加内容;

    参数设置:

    前三个参数很好写,第四个参数是一个函数指针,得需要自己根据类型来编写

    例如现在编排一个整形类型

     接收参数:

    注:因为我们要编写一个适应于全类型的函数,所有第一个参数用void*来接收

     编写cmp函数中的参数:

    接下来我们应该开始比对大小,我们要编写一个适用于全类型的函数来进行比对大小

    我们可以套用我们写的cmp函数 因为它那个就是比较大小的 

    难点就是如何获取他们要比较的e1和e2的地址

    因为我们不知道是什么类型的排序,所有我们先给它强制转化为(char*)类型的(char* 类型的变量加减是一个一个字节加减的),随后跟size这个参数我们便能知道它们每个字节占的大小 ,我们就能获取到每一个元素的地址

    交换顺序:

     交换我们最好编写一个函数

    注:因为是char*类型,它是一个字节一个字节交换,我们把它的size传过去即可

    5.整体展示

    int类型:

    1. #include
    2. void swap(char* buf1, char* buf2, int size)
    3. {
    4. int i;
    5. for (i = 0; i < size; i++)
    6. {
    7. char tmp = *buf1;
    8. *buf1 = *buf2;
    9. *buf2 = tmp;
    10. buf1++;
    11. buf2++;
    12. }
    13. }
    14. void bubble_sort(void *base, int sz,int size,int (*cmp)(const void* e1,const void* e2))
    15. {
    16. int i;
    17. for (i = 0; i < sz - 1; i++)
    18. {
    19. int j;
    20. for (j = 0; j < sz - i - 1; j++)
    21. {
    22. if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
    23. {
    24. swap( (char*)base + j * size , (char*)base + (j + 1) * size , size);
    25. }
    26. }
    27. }
    28. }
    29. int cmp_int(const void* e1, const void* e2)
    30. {
    31. return *(int*)e1 - *(int*)e2;
    32. }
    33. test1()
    34. {
    35. int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
    36. int sz = sizeof(arr) / sizeof(arr[0]);
    37. bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
    38. int i;
    39. for (i = 0; i < sz; i++)
    40. {
    41. printf("%d ", arr[i]);
    42. }
    43. }
    44. int main()
    45. {
    46. test1();
    47. }

     排序一个结构体类型的数据,按名字排序:

    1. #include
    2. struct stu
    3. {
    4. char name[10];
    5. int age;
    6. };
    7. void swap(char* buf1, char* buf2, int size)
    8. {
    9. int i;
    10. for (i = 0; i < size; i++)
    11. {
    12. char tmp = *buf1;
    13. *buf1 = *buf2;
    14. *buf2 = tmp;
    15. buf1++;
    16. buf2++;
    17. }
    18. }
    19. void bubble_sort(void* base, int sz, int size, int (*cmp)(const void* e1, const void* e2))
    20. {
    21. int i;
    22. for (i = 0; i < sz - 1; i++)
    23. {
    24. int j;
    25. for (j = 0; j < sz - i - 1; j++)
    26. {
    27. if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
    28. {
    29. swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
    30. }
    31. }
    32. }
    33. }
    34. int cmp_by_name(const void* e1, const void* e2)
    35. {
    36. return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name);
    37. }
    38. int main()
    39. {
    40. struct stu s[] = { {"zhangsan",15},{"lisi",18},{"wangwu",11},"mahua",8 };
    41. int sz = sizeof(s) / sizeof(s[0]);
    42. bubble_sort(s, sz, sizeof(s[0]), cmp_by_name);
    43. int i;
    44. for (i = 0; i < sz; i++)
    45. {
    46. printf("%s ", s[i].name);
    47. }
    48. }

  • 相关阅读:
    Sping源码(九)—— Bean的初始化(非懒加载)— doGetBean
    RPC接口测试技术-websocket 自动化测试实践
    vite和webpack的区别
    java计算机毕业设计小区停车场信息系统源码+系统+数据库+lw文档+mybatis+运行部署
    实战:实现一个LRU
    STM32的GPIO端口的八种模式解析
    盲盒商城怎样抓住用户的心
    剑指offer专项突击版第29天
    jvm调优 和实际案例
    Java 多态具体指什么?怎么使用多态?
  • 原文地址:https://blog.csdn.net/chaodddddd/article/details/132893115