• 数据结构-快速排序-C语言实现


    引言:快速排序作为一种非常经典且高效的排序算法,无论是工作还是面试中广泛用到,作为一种分治思想,需要熟悉递归思想。下面来讲讲快速排序的实现和改进。

    老规矩,先用图解来理解一下:(这里使用快速排序中的“挖坑法”)

    笔误:下面这个图right是--的! 

     

     

      以此往复

    下面是代码:

    1. void dfs_quick_sort(int* arry, int left, int right) {
    2. if ((right - left) <= 0) return;
    3. //添加一个三数取中的操作
    4. int key = arry[left];
    5. int end = right;
    6. int begin = left;
    7. while (left < right) {
    8. while (left < right && arry[right] >= key) {
    9. right--;
    10. }
    11. arry[left] = arry[right];
    12. while (left < right && arry[left] <= key) {
    13. left++;
    14. }
    15. arry[right] = arry[left];
    16. }
    17. arry[right] = key;
    18. dfs_quick_sort(arry,begin, left - 1);
    19. dfs_quick_sort(arry,right + 1, end);
    20. }
    21. //挖坑法
    22. void quick_sort(int* arry, int size) {
    23. assert(arry);
    24. dfs_quick_sort(arry, 0, size - 1);
    25. }

    测试代码:

    1. void test_quick_sort(int* arry, int size) {
    2. Printf(arry, size);
    3. quick_sort(arry, size);
    4. Printf(arry, size);
    5. }
    6. int main() {
    7. int arry[] = { 2,3,1,6,21,78,11,36,11,11,9 };
    8. int len = sizeof(arry) / sizeof(arry[0]);
    9. //test_insertion_sort(arry, len);
    10. //est_shell_sort(arry, len);
    11. //test_select_sort(arry, len);
    12. //test_heap_sort(arry, len);
    13. //test_bubble_sort(arry, len);
    14. test_quick_sort(arry, len);
    15. return 0;
    16. }

    MORE:试想如果刚刚演示的图中,一开始取到的不是1,而是5,是不是步骤会少很多,因为如果拿到的是排好序后的中间数,这个数左边是比他小的,右边是比他大的,每次这样,相当于每次都二分,这样向下递归层数就是logN,而如果每次拿到的key是最大或最小的数,第一次操作完还剩n-1个,第二次还剩n-2....。层数为n层,时间复杂度为N^2。

    所以我们要尽量选到一个靠近排序好的中间的数,不要选到最大或最小的数为key。

    下面将代码进行改进:(取最左边和最右边和中间三个值中的中间数)

    1. int mid_quick_number(int* arry, int left, int right) {
    2. int mid = left + (right - left >> 1);//去中间数防止普通求中间数溢出问题
    3. if (arry[mid] > arry[left]) {
    4. if (arry[right] > arry[mid]) {
    5. mid = mid;
    6. }
    7. else if(arry[right]>arry[left]){
    8. mid = right;
    9. }
    10. else {
    11. mid = left;
    12. }
    13. }
    14. else {
    15. if (arry[right] < arry[mid]) {
    16. mid = mid;
    17. }
    18. else if (arry[right] > arry[left]) {
    19. mid = left;
    20. }
    21. else {
    22. mid = right;
    23. }
    24. }
    25. return mid;
    26. }
    27. void dfs_quick_sort(int* arry, int left, int right) {
    28. if ((right - left) <= 0) return;
    29. //添加一个三数取中的操作
    30. int mid = mid_quick_number(arry, left, right);
    31. swap(arry + mid, arry+left);
    32. int key = arry[left];
    33. int end = right;
    34. int begin = left;
    35. while (left < right) {
    36. while (left < right && arry[right] >= key) {
    37. right--;
    38. }
    39. arry[left] = arry[right];
    40. while (left < right && arry[left] <= key) {
    41. left++;
    42. }
    43. arry[right] = arry[left];
    44. }
    45. arry[right] = key;
    46. dfs_quick_sort(arry,begin, left - 1);
    47. dfs_quick_sort(arry,right + 1, end);
    48. }
    49. //挖坑法
    50. void quick_sort(int* arry, int size) {
    51. assert(arry);
    52. dfs_quick_sort(arry, 0, size - 1);
    53. }
  • 相关阅读:
    Linux系统配置 Samba客户端
    LeetCode 热题 HOT 100:回溯专题
    Conda管理Python不同版本教程
    Doris代码结构
    怒刷LeetCode的第19天(Java版)
    硬件寿命警告!Windows11在特定情况下对【固态硬盘】执行与【机械硬盘】相同的磁盘碎片整理。
    LayaBox---TypeScript---枚举
    如何降低复杂度,用数据库做消息队列的存储?
    MySQL的增删查改(CRUD)
    Structed Streaming入门--Scala篇
  • 原文地址:https://blog.csdn.net/weixin_56821642/article/details/133394742