zoukankan      html  css  js  c++  java
  • 快速排序的主要优化

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

    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

  • 相关阅读:
    627. Swap Salary
    176. Second Highest Salary
    596. Classes More Than 5 Students
    183. Customers Who Never Order
    181. Employees Earning More Than Their Managers
    182. Duplicate Emails
    175. Combine Two Tables
    620. Not Boring Movies
    595. Big Countries
    HDU 6034 Balala Power! (贪心+坑题)
  • 原文地址:https://www.cnblogs.com/maples7/p/4478076.html
Copyright © 2011-2022 走看看