• 模拟实现qsort函数(冒泡排序版本)


    作者:~小明学编程

    文章专栏:C语言基础知识

    目之所及皆为回忆,心之所想皆为过往
    在这里插入图片描述

    今天给大家介绍C语言中一个比较好用的函数qsort函数以及我们模拟实现qsort函数的过程。

    目录

    qsort函数

    作用

    参数

    用法

    模拟实现qsort函数


    qsort函数

    这里是qsort函数的介绍,在这里简单的给大家翻译介绍一下

    作用

    首先最上面说到它的作用,执行一个快速排序,qsort函数是一个排序函数,它的底层排序算法是快速排序。

    参数

    void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

    接着就是它的返回值和参数,我们可以看到这长长的一串,看着就头疼,不过也没大家想象的那么复杂,给大家介绍一下大家就明白了。

    首先看我们的第一个参数base,就是一个我们待排序的数组,接着就是num,顾名思义就是我们数组元素的的大小,待排序元素的个数,然后就是width参数,也就是我们待排元素中每个元素的大小,最后就是int (__cdecl *compare )(const void *elem1, const void *elem2 )这是一个回调函数,其中compare是一个函数指针,函数的两个参数分别是elem1和elem2(类型是void*)返回值是int类型,最后qsort的返回类型是void型。

    用法

    下面就给大家介绍一下qsot函数的用法

    1. //整数的比较
    2. int cmp1(const void* e1, const void* e2)
    3. {
    4. return *((int*)e1) - *((int*)e2);
    5. }
    6. //测试整数
    7. void test1()
    8. {
    9. int arr[5] = { 5,4,3,2,1 };
    10. int sz = sizeof(arr) / sizeof(arr[0]);
    11. my_qsort(arr, sz, sizeof(arr[0]), cmp1);
    12. for (int i = 0; i < 5; i++)
    13. {
    14. printf("%d ", arr[i]);
    15. }
    16. printf("\n");
    17. }
    18. int main()
    19. {
    20. test1();
    21. return 0;
    22. }

    这个比较函数是需要我们自己去设计的,根据我们所比较的类型不同我们可以设计不同的比较函数

    1. //浮点数的比较
    2. int cmp2(const void* e1, const void* e2)
    3. {
    4. return *((double*)e1) - *((double*)e2);
    5. }
    6. //字符的比较
    7. int cmp3(const void* e1, const void* e2)
    8. {
    9. return *((char*)e1) - *((char*)e2);
    10. }
    11. //字符串的比较
    12. int cmp4(const void* e1, const void* e2)
    13. {
    14. return strcmp(*(char**)e1, *(char**)e2);
    15. }
    16. //结构体数字比较
    17. int cmp5(const void* e1, const void* e2)
    18. {
    19. return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
    20. }
    21. //结构体字符串比较
    22. int cmp6(const void* e1, const void* e2)
    23. {
    24. return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
    25. }

    下面是我们对一个整数数组的排序

    模拟实现qsort函数

    1. //模拟实现qsort函数
    2. void swap(char* ch1, char* ch2, int sz)
    3. {
    4. for (int i = 0; i < sz; i++)
    5. {
    6. char tem = *ch1;
    7. *ch1 = *ch2;
    8. *ch2 = tem;
    9. ch1++;
    10. ch2++;
    11. }
    12. }
    13. void my_qsort(void* arr, int num, int size, int (*cmp)(const void* e1, const void* e2))
    14. {
    15. for (int i = 0; i < num; i++)
    16. {
    17. for (int j = 0; j < num - i - 1; j++)
    18. {
    19. //cmp((char*)arr + j * size, (char*)arr + (j + 1) * size)
    20. if (cmp((char*)arr + j * size, (char*)arr + (j + 1) * size))
    21. {
    22. swap((char*)arr + j * size, (char*)arr + (j + 1) * size, size);
    23. }
    24. }
    25. }
    26. }

    其中我们判断大小之后要进行一个交换,交换的过程我们采用的是逐个字节进行交换,也就是我们的swap函数所实现的功能。

    下面是我们对各种类型的比较

    1. #include
    2. #include
    3. #include
    4. struct Stu
    5. {
    6. int age;
    7. char name[20];
    8. };
    9. //整数的比较
    10. int cmp1(const void* e1, const void* e2)
    11. {
    12. return *((int*)e1)-*((int*)e2);
    13. }
    14. //浮点数的比较
    15. int cmp2(const void* e1, const void* e2)
    16. {
    17. return *((double*)e1) - *((double*)e2);
    18. }
    19. //字符的比较
    20. int cmp3(const void* e1, const void* e2)
    21. {
    22. return *((char*)e1) - *((char*)e2);
    23. }
    24. //字符串的比较
    25. int cmp4(const void* e1, const void* e2)
    26. {
    27. return strcmp(*(char**)e1, *(char**)e2);
    28. }
    29. //结构体数字比较
    30. int cmp5(const void* e1, const void* e2)
    31. {
    32. return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
    33. }
    34. //结构体字符串比较
    35. int cmp6(const void* e1, const void* e2)
    36. {
    37. return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
    38. }
    39. //模拟实现qsort函数
    40. void swap(char* ch1, char* ch2, int sz)
    41. {
    42. for (int i = 0; i < sz; i++)
    43. {
    44. char tem = *ch1;
    45. *ch1 = *ch2;
    46. *ch2 = tem;
    47. ch1++;
    48. ch2++;
    49. }
    50. }
    51. void my_qsort(void* arr, int num, int size, int (*cmp)(const void* e1, const void* e2))
    52. {
    53. for (int i = 0; i < num; i++)
    54. {
    55. for (int j = 0; j < num - i - 1; j++)
    56. {
    57. //cmp((char*)arr + j * size, (char*)arr + (j + 1) * size)
    58. if (cmp((char*)arr + j * size, (char*)arr + (j + 1) * size))
    59. {
    60. swap((char*)arr + j * size, (char*)arr + (j + 1) * size, size);
    61. }
    62. }
    63. }
    64. }
    65. //测试整数
    66. void test1()
    67. {
    68. int arr[5] = { 5,4,3,2,1 };
    69. int sz = sizeof(arr) / sizeof(arr[0]);
    70. my_qsort(arr, sz, sizeof(arr[0]), cmp1);
    71. for (int i = 0; i < 5; i++)
    72. {
    73. printf("%d ", arr[i]);
    74. }
    75. printf("\n");
    76. }
    77. //测试浮点数
    78. void test2()
    79. {
    80. double arr[5] = { 2.5,2.3,3.8,6.1,0.2 };
    81. int sz = sizeof(arr) / sizeof(arr[0]);
    82. my_qsort(arr, sz, sizeof(arr[0]), cmp2);
    83. for (int i = 0; i < 5; i++)
    84. {
    85. printf("%.1lf ", arr[i]);
    86. }
    87. printf("\n");
    88. }
    89. //测试字符
    90. void test3()
    91. {
    92. char arr[5] = { 'e','f','o','a','q' };
    93. int sz = sizeof(arr) / sizeof(arr[0]);
    94. my_qsort(arr, sz, sizeof(arr[0]), cmp3);
    95. for (int i = 0; i < 5; i++)
    96. {
    97. printf("%c ", arr[i]);
    98. }
    99. printf("\n");
    100. }
    101. //测试字符串
    102. void test4()
    103. {
    104. char* arr[] = { "shan","huani","ajfie","deygufefb" };
    105. int sz = sizeof(arr) / sizeof(arr[0]);
    106. my_qsort(arr, sz, sizeof(arr[0]), cmp4);
    107. for (int i = 0; i < sz; i++)
    108. {
    109. printf("%s ", arr[i]);
    110. }
    111. printf("\n");
    112. }
    113. //测试结构体中的排序
    114. void test5()
    115. {
    116. struct Stu arr[4] = { {11,"uheriu"},{37,"iuehen"},{8,"aouenioon"},{22,"ming"} };
    117. int sz = sizeof(arr) / sizeof(arr[0]);
    118. my_qsort(arr, sz, sizeof(arr[0]), cmp5);
    119. for (int i = 0; i < sz; i++)
    120. {
    121. printf("%d ", arr[i].age);
    122. }
    123. printf("\n");
    124. my_qsort(arr, sz, sizeof(arr[0]), cmp6);
    125. for (int i = 0; i < sz; i++)
    126. {
    127. printf("%s ", arr[i].name);
    128. }
    129. }
    130. int main()
    131. {
    132. test1();
    133. test2();
    134. test3();
    135. test4();
    136. test5();
    137. return 0;
    138. }

  • 相关阅读:
    Dockerfile RUN
    MySQL学习笔记23
    MySQL 事务隔离级别与锁机制详解
    【EC200U】何为QuecPython以及QPYcom基础操作
    MySQL常考知识点
    Yolov8-pose关键点检测:模型轻量化创新 | ScConv结合c2f | CVPR2023
    【虚幻引擎UE】UE5 两种球体绘制方法
    Uber 应用分享 | 使用 Parquet Page Index 加速 Presto 查询
    力扣(LeetCode)18. 四数之和(C++)
    数据结构与算法之美学习笔记:18 | 散列表(上):Word文档中的单词拼写检查功能是如何实现的?
  • 原文地址:https://blog.csdn.net/m0_56911284/article/details/126318991