快速排序中分区算法的延伸——划分多个区间
来源:互联网 发布:淘宝客新建导购推广 编辑:程序博客网 时间:2024/06/06 14:16
按照自己的理解,分区算法partition的核心在于:索引的变换和交换元素,也就是说按照索引将不同的元素交换到不同的区间。快排中的partition只划分了2个区间:小等于以及大于。在这里,我们划分3个区间:小于、等于和大于,若给定数组arr{1,2,3,4,0,2},最后一个2设为主元nPivot,则经过分区后的数组也许为arr{1,0,2,2,4,3}(先不管相同区间的元素顺序)。
划分3个区间的思路(以上面的数组为例):设2个索引值,分别指向0和第2个2,记为nBeforeEqual和nBeforeLarge,同时用i遍历整个数组。
1.若arr[i] > nPivot,啥都不做。
2.若arr[i] == nPivot,交换arr[nBeforeLarge+1]和arr[i],若数字序列为1,0,4,2,此时i指向2,nBeforeLarge指向0,则交换4和2即可,变成1,0,2,4。
3.若arr[i] < nPivot, 先交换arr[nBeforeLarge+1]和arr[i],再交换arr[nBeforeLarge+1]和arr[nBeforeEqual+1],也就是说先把小元素交换到等于这个区间,再交换到小于这个区间,若数字序列为1,2,4,0,此时i指向0,nBeforeLarge指向2,nBeforeEqual指向1,先交换0和4,变成1,2,0,4,再交换2和0,变成1,0,2,4。
最后,再交换arr[nBeforeEqual+1]和nPivot,把主元交换到等于区间,完成分区。
代码如下:
<span style="font-size:24px;">template<typename T>CNumPair partition(T* pArr, int nLeft, int nRight){int nPivot = pArr[nRight];int nBeforeEqual = nLeft-1;int nBeforeLarge = nLeft-1;for (int i = nLeft; i <= nRight; ++i){if (pArr[i] < nPivot){++nBeforeLarge;swap(pArr+nBeforeLarge, pArr+i);++nBeforeEqual;swap(pArr+nBeforeLarge, pArr+nBeforeEqual);}else if (pArr[i] == nPivot){++nBeforeLarge;swap(pArr+nBeforeLarge, pArr+i);}}swap(pArr+nBeforeLarge+1, pArr+nRight);return CNumPair(nBeforeEqual+1, nBeforeLarge+1);}</span>
同样,如果需要划分4个,5个区间,只需要多设几个索引值,每遍历一个元素,逐渐交换,一直换到对应的区间。
OVER
- 快速排序中分区算法的延伸——划分多个区间
- 快速排序中的区间划分
- 快速排序之区间划分
- 高级排序-快速排序-利用三数据取中划分的快速排序算法
- 划分算法(快速排序的根基)
- 数据结构-快速排序-划分算法
- (原创)选择排序与快速排序及D&C算法的延伸
- 排序算法之三路划分的快速排序
- 快速排序的划分算法的总结和思考
- Algorithm--让人困惑的快速排序(划分算法)
- Algorithm--让人困惑的快速排序(划分算法) 续
- 算法<基于三路划分的快速排序>
- <算法>基于三路划分的链表快速排序
- 双向划分的快速排序
- 快速排序的Hoare划分
- 快速排序的三者取中划分
- 快速排序与其中的划分算法
- (十五)高级排序—划分算法
- hdoj 3336 Count the string 【KMP】
- 简单验证码的有关知识点
- Objective-C简介
- 最简洁的nginx反向代理例子配置
- Word Search II 题解
- 快速排序中分区算法的延伸——划分多个区间
- 可变长参数示例
- C++自制Redis 数据库(九) 详细数据库存储结构,线程相关已解决
- URAL1534 进球
- connot be resolved to a variable
- Maven异常:Dynamic Web Module 3.0 requires Java 1.6 or newer.
- 1016. 部分A+B
- BZOJ 1112 POI2008 砖块
- 6.2、朴素贝叶斯实例