您的位置:首页 > 其它

快速排序的主要优化

2015-05-05 00:18 381 查看
对于快排的优化大概有这样几点:

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

// 快排: 选定轴点
int parti(int lo, int hi)
{
swap(num[lo], num[lo + rand() % (hi - lo + 1)]);
int pivot = num[lo];
     while (lo < hi)
{
while ((lo < hi) && (pivot <= num[hi])) hi--;
num[lo] = num[hi];
         while ((lo < hi) && (num[lo] <= pivot)) lo++;
num[hi] = num[lo];
     }
num[lo] = pivot;
     return lo;
}


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

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

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

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

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

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

// 快排: 选定轴点
int parti(int lo, int hi)
{
swap(num[lo], num[lo + rand() % (hi - lo + 1)]);
int pivot = num[lo];
while (lo < hi)
{
while (lo < hi)
  {
  if (pivot < num[hi]) hi--;
  else
  {
   num[lo++] = num[hi];
    break;
    }
    }
   while (lo < hi)
    {
    if (num[lo] < pivot)) lo++;
   else
    {
      num[hi--] = num[lo];
       break;
   }
    }
}
num[lo] = pivot;
return lo;
}


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

From:我的知乎回答:http://www.zhihu.com/question/19841543/answer/46760856
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: