/*
* 排序的核心算法
*
* @param array
* 待排序数组
* @param startIndex
* 开始位置
* @param endIndex
* 结束位置
*/
private void sortCore(int[] array, int startIndex, int endIndex) {
if (startIndex >= endIndex) {
return;
}
int boundary = boundary(array, startIndex, endIndex);
sortCore(array, startIndex, boundary - 1);
sortCore(array, boundary + 1, endIndex);
}
/*
* 交换并返回分界点
*
* @param array
* 待排序数组
* @param startIndex
* 开始位置
* @param endIndex
* 结束位置
* @return
* 分界点
*/
private int boundary(int[] array, int startIndex, int endIndex) {
int standard = array[startIndex]; // 定义标准
int leftIndex = startIndex; // 左指针
int rightIndex = endIndex; // 右指针
while(leftIndex < rightIndex) {
while(leftIndex < rightIndex && array[rightIndex] >= standard) {
rightIndex--;
}
array[leftIndex] = array[rightIndex];
while(leftIndex < rightIndex && array[leftIndex] <= standard) {
leftIndex++;
}
array[rightIndex] = array[leftIndex];
}
array[leftIndex] = standard;
return leftIndex;
}
复杂度分析
排序方法 | 时间复杂度 | 空间复杂度 | 稳定性 | 复杂性 | ||
---|---|---|---|---|---|---|
平均情况 | 最坏情况 | 最好情况 | ||||
快速排序 | O(nlog2n) | O(n2) | O(nlog2n) | O(log2n) | 不稳定 | 较复杂 |
这里我们可以做一些关于复杂度的推理。
如果我们在选取基准p的时候,每次选取的都是当前数组中最小的一个元素,那么每次划分都只是让数组中的元素少1(被筛选出来的那个元素当然有序),这样一来就需要反复遍历数组导致复杂度变成了O(n2)。
如果我们在选取基准p的时候,每次选取的都是当前数组中最中间的一个元素(是中位数,而不是元素位置上的中间),那么每次划分都把当前数组划分成了长度相等的两个子数组,这样一来复杂度变成了O(nlog2n)。