快速排序的主要优化
2015-05-05 00:18
381 查看
对于快排的优化大概有这样几点:
1、减少 swap 次数 或者 直接不用 swap 操作,从整体上考虑每次 (i, j)元素的交换,让每次元素对之间的交换变成整体上的挪位(这样也不需要借助临时变量):
表现在有下划线的代码上。
2、对于轴点的选取,要使左右集合的规模尽可能相当。
可以采取的方法有:随机选取法、三者取中法。
相比而言,对于最坏情况产生的概率,三者取中法又比随机选取法更能有效避免。
3、对于退化情形的考虑,即重复元素。
可以将上述选取轴点代码优化为:
这样对于全部都是一样的元素,也能将轴点选取在中点位置而不会退化为最坏情况。代价是实际上的交换变多了。
From:我的知乎回答:http://www.zhihu.com/question/19841543/answer/46760856
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
相关文章推荐
- 快速排序 冒泡排序 归并排序 堆排序 的主要代码
- 快速排序的优化及其与qsort的比较
- 快速排序的复杂度分析以及使用插入排序优化的快速排序
- java快速排序-原始未优化
- 快速排序的优化
- 快速排序 优化 详细分析
- C++学习 - 快速排序,更加优化的实现
- 快速排序的两种实现方式,主要是Partition函数的实现原理不一样
- 快速排序的JAVA实现、优化和应用
- 快速排序的几种方法及其优化
- 算法导论学习笔记(一)快速排序及优化
- 快速排序的优化
- java 快速排序 优化 以及扩展到对象 List 集合
- 优化 快速排序
- 快速排序 优化 详细分析
- java快速排序优化
- 《大话数据结构》读书笔记之快速排序源码及其优化
- 起泡排序的进一步优化:快速排序
- Java排序算法优化--快速排序【温故而知新】
- 快速排序优化