码迷,mamicode.com
首页 > 编程语言 > 详细

快速排序的主要优化

时间:2015-05-05 01:15:31      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

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

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

快速排序的主要优化

标签:

原文地址:http://www.cnblogs.com/maples7/p/4478076.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!