您现在的位置是:首页 >技术杂谈 >Java 11 sort DualPivotQuicksort 源码中的sort详解网站首页技术杂谈
Java 11 sort DualPivotQuicksort 源码中的sort详解
简介Java 11 sort DualPivotQuicksort 源码中的sort详解
static void sort(int[] a, int left, int right, int[] work, int workBase, int workLen)
- 判断排序阈值:
- 如果待排序数组的长度小于设定的阈值QUICKSORT_THRESHOLD,则直接使用快速排序算法进行排序。
- private static final int QUICKSORT_THRESHOLD = 286;
- 如果待排序数组的长度小于设定的阈值QUICKSORT_THRESHOLD,则直接使用快速排序算法进行排序。
- 检查数组的有序性:
- 通过遍历数组,检查数组是否已经是部分有序的。这里的有序是指数组中存在多个连续的升序或降序的序列(称为run)。这个过程中,如果发现降序的序列,会将其转换为升序。同时,如果发现相邻的两个序列是升序的,会将它们合并为一个序列。
- 判断是否使用快速排序:
- 如果在上一步中发现的序列数量超过了设定的最大值MAX_RUN_COUNT,则认为数组的有序性不强,直接使用快速排序算法进行排序。
- private static final int MAX_RUN_COUNT = 67;
- 处理特殊情况:
- 如果数组完全有序(只有一个序列),或者只有一个序列并且这个序列的结束位置就是数组的结束位置,那么不需要进行任何操作,直接返回。
- 准备合并:
- 如果数组中存在多个序列,那么需要进行合并操作。首先,会检查是否需要创建一个临时的工作数组用于合并。然后,根据序列的数量的奇偶性,决定是在原数组上进行合并,还是在临时数组上进行合并。
- 进行合并:
- 最后,进行多轮的合并操作,每一轮都会将相邻的两个序列合并为一个序列,直到只剩下一个序列为止。在这个过程中,会不断地在原数组和临时数组之间进行切换。
private static void sort(int[] a, int left, int right, boolean leftmost)
- 判断排序阈值:
- 如果待排序数组的长度小于设定的阈值INSERTION_SORT_THRESHOLD,则使用插入排序算法进行排序。插入排序对于小数组来说效率较高。
- private static final int INSERTION_SORT_THRESHOLD = 47;
- 选择轴点:
- 如果待排序数组的长度大于设定的阈值,那么需要选择两个轴点用于快速排序。这里选择了数组中五个等间距的元素(包括中点),并使用插入排序对它们进行排序。然后选择第二个和第四个元素作为轴点。
- 分区:
- 根据选择的轴点,将数组分为三个部分:小于第一个轴点的部分,位于两个轴点之间的部分,大于第二个轴点的部分。在这个过程中,会将等于轴点的元素移动到正确的位置。
- 递归排序:
- 对分区后的左部分和右部分进行递归排序。对于中间部分,如果它的长度过大(占整个数组的4/7以上),那么会再次进行分区和排序;否则,由于中间部分的所有元素都等于轴点,所以已经是有序的,不需要再进行排序。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。