• 快速排序的主要优化


    对于快排的优化大概有这样几点:

    1、减少 swap 次数 或者 直接不用 swap 操作,从整体上考虑每次 (i, j)元素的交换,让每次元素对之间的交换变成整体上的挪位(这样也不需要借助临时变量):

     1 // 快排: 选定轴点
     2 int parti(int lo, int hi)
     3 {
     4     swap(num[lo], num[lo + rand() % (hi - lo + 1)]);
     5     int pivot = num[lo];
     6     while (lo < hi)
     7     {
     8         while ((lo < hi) && (pivot <= num[hi])) hi--;
     9         num[lo] = num[hi];
    10         while ((lo < hi) && (num[lo] <= pivot)) lo++;
    11         num[hi] = num[lo];
    12     }
    13     num[lo] = pivot;
    14     return lo;
    15 }

    表现在有下划线的代码上。

    2、对于轴点的选取,要使左右集合的规模尽可能相当。

      可以采取的方法有:随机选取法、三者取中法。

      相比而言,对于最坏情况产生的概率,三者取中法又比随机选取法更能有效避免。

    3、对于退化情形的考虑,即重复元素。

      可以将上述选取轴点代码优化为:

     1 // 快排: 选定轴点
     2 int parti(int lo, int hi)
     3 {
     4     swap(num[lo], num[lo + rand() % (hi - lo + 1)]);
     5     int pivot = num[lo];
     6     while (lo < hi)
     7     {
     8         while (lo < hi) 
     9       {
    10           if (pivot < num[hi]) hi--;
    11           else 
    12           {
    13               num[lo++] = num[hi];
    14               break;
    15           }
    16       }
    17       while (lo < hi) 
    18       {
    19           if (num[lo] < pivot)) lo++;
    20           else
    21           {
    22               num[hi--] = num[lo];
    23               break;
    24           }
    25       }
    26     }
    27     num[lo] = pivot;
    28     return lo;
    29 }

    这样对于全部都是一样的元素,也能将轴点选取在中点位置而不会退化为最坏情况。代价是实际上的交换变多了。

    From:我的知乎回答:http://www.zhihu.com/question/19841543/answer/46760856

  • 相关阅读:
    apache域名跳转
    apache配置防盗链
    apache配置静态缓存
    apache通过rewrite限制某个目录
    apache不记录指定类型的访问日志
    apache访问日志
    apache用户认证
    apache访问控制
    apache禁止默认虚拟主机
    mysql主从复制架构配置
  • 原文地址:https://www.cnblogs.com/maples7/p/4478076.html
Copyright © 2020-2023  润新知