目录
1. 快速排序
2. 三向切分快速排序 - Java 实现
/**
* 快速排序三向切分
*
* @param nums 待排序数组
*/
public void quickSortThreeWay(int[] nums) {
sortThreeWay(nums, 0, nums.length - 1);
}
/**
* 三向切分
*
* @param nums 排序数组
* @param lo 当前排序区间,左节点下标
* @param hi 当前排序区间,右节点下标
*/
public void sortThreeWay(int[] nums, int lo, int hi) {
// 退出条件
if (lo >= hi) {
return;
}
// nums[left] 作为分区值
int left = lo;
int right = hi;
int mid = left + 1;
/* 处理结果
* [lo ~ left-1] 小于分区值
* [left ~ right] 等于分区值
* [right+1 ~ hi] 大于分区值
*/
while (mid <= right) {
if (nums[mid] > nums[left]) {
swap(nums, mid, right);
right--;
} else if (nums[mid] < nums[left]) {
swap(nums, mid, left);
mid++;
left++;
} else {
mid++;
}
}
// 对小于当前分区值的区间排序
sortThreeWay(nums, lo, left - 1);
// 对大于当前分区值的区间排序
sortThreeWay(nums, right + 1, hi);
}
3. 标准快排与三向切分快排效率对比
排序数值范围 | 标准快速排序 | 三向切分快速排序 |
---|---|---|
0-500 | 11.439 | 0.313 |
0-5000 | 2.534 | 0.592 |
0-50000 | 0.705 | 0.626 |
0-500000 | 0.670 | 0.893 |
0-5000000 | 0.701 | 1.145 |
0-50000000 | 0.698 | 1.111 |
排序数值范围 | 标准快速排序 | 三向切分快速排序 |
---|---|---|
0-50000 顺序 | 0.508 | 0.041 |
0-50000 逆序 | 0.593 | 4.702 |
数据为随机生成,标准快排、三向切分快排,在同数据范围下的原始排序数组数据分布情况一致。
排序时间因不同设备不同数据情况会有不同,仅供参考
4. 总结
三向切分快排,区分了大于分区值、小于分区值、等于分区值三个区间。等于分区值的区间不参与后续排序,避免了重复数据之间的排序。
- 重复元素越多,三向切分快排效率越高。
- 数据越有序,三向切分快排效率越高。