• 快速排序的优化


    1.在极端情况下的优化

    上一篇文章中,我们提到了一个时间复杂度

    最优时间复杂度:O(nlogn)-- 每次找到的都是中间值

    最坏时间复杂度:O(n^2)-- 有序数组或者接近有序

    在这看来,快速排序的时间复杂度还无法确定,所以我们会对代码进一步优化。

    2.三数取中法

    思维如下:

    取三个数,分别为 begin , mid , end 代表数组的首元素,中间元素,和末尾元素。将他们对应的值进行比较,取三数中间大小的为keyi,然后加入快速排序的函数中,再细微调整。

    代码如下,使用简单的if-else 判断,就可以得到中间值下标mid

    1. int GetMidIndex(int* a, int left, int right)
    2. {
    3. int mid = (left + right) / 2;
    4. if (a[left] > a[mid])
    5. {
    6. if (a[mid] >= a[right])
    7. {
    8. return mid;
    9. }
    10. else
    11. {
    12. if (a[right] > a[left])
    13. {
    14. return left;
    15. }
    16. else
    17. {
    18. return right;
    19. }
    20. }
    21. }
    22. else//left<= mid
    23. {
    24. if (a[mid] < a[right])
    25. {
    26. return mid;
    27. }
    28. else
    29. {
    30. if (a[right] > a[left])
    31. {
    32. return right;
    33. }
    34. else
    35. {
    36. return left;
    37. }
    38. }
    39. }
    40. }
    41. int PartSort1(int* a, int left, int right)
    42. {
    43. int mid = GetMidIndex(a, left, right);
    44. Swap(&a[left], &a[mid]);

    逻辑很简单,可以自己尝试一下哟


    3.快速排序非递归

    之前的代码:

    1. void QuickSort(int* a, int begin, int end)
    2. {
    3. if (begin >= end)
    4. {
    5. return;
    6. }
    7. int keyi = PartSort3(a, begin, end);
    8. QuickSort(a, begin, keyi - 1);
    9. QuickSort(a, keyi + 1, end);
    10. }

    使用过递归实现的,所以所需要的空间是在栈上面进行的。但是栈的空间很小,在达到一定程度的深度调用就会引起爆栈。所以,我们接下来是想让程序最好能在堆上运行(堆的大小单位为G),而栈的话一般只有64KB,所以啦,我们接下来学习的非递归版很有用处哟:

    1. //快速排序非递归版
    2. void QuickSortNon(int* a, int begin, int end)
    3. {
    4. ST st;
    5. StackInit(&st);
    6. StackPush(&st, end);
    7. StackPush(&st, begin);
    8. while (!StackEmpty(&st))
    9. {
    10. int left = StackTop(&st);
    11. StackPop(&st);
    12. int right = StackTop(&st);
    13. StackPop(&st);
    14. int keyi = PartSort3(a, left, right);
    15. if ( keyi + 1 < right)
    16. {
    17. StackPush(&st, right);
    18. StackPush(&st, keyi + 1);
    19. }
    20. if (left < keyi - 1)
    21. {
    22. StackPush(&st, keyi - 1);
    23. StackPush(&st, left);
    24. }
    25. }
    26. StackDestroy(&st);
    27. }

    在这里需要和栈结合起来,通过栈的特点来达到,我们可以达到类似于递归过程的非递归的方法。

  • 相关阅读:
    webfunny埋点漏斗功能
    postgres in (?,?) 和 =any(?) 用法/性能对比
    玩机搞机----安卓全机型修改 开机动画 步骤教程
    Python机器学习实战-建立Gradient Boosting模型预测肾脏疾病(附源码和实现效果)
    神经网络的过拟合是什么,神经网络解决过拟合
    《C++编程思想》笔记
    计数排序算法
    良好的测试环境应该怎么搭建?对软件产品起到什么作用?
    从可逆计算看DSL的设计要点
    SpringMVC中文件的上传与下载
  • 原文地址:https://blog.csdn.net/2203_75523573/article/details/133781185