1.基本思想
快速排序是迄今为止所有内排序算法中速度最快的一种。基本思想是:任取待排序序列中的某个元素作为基准(一般取第一个元素),通过一次划分,将待排序元素分为左右两个子序列,左子序列元素的值都小于基准元素的值,右子序列元素的值都大于等于基准元素的值,然后分别对两个子序列继续进行划分,直至每一个子序列只有一个元素为止。最后的得到的序列便是有序序列。(代码的话看实现方式一、实现方式三就可以了)
2.一次划分的具体过程
① low 指向待划分区域首元素,high 指向待划分区域尾元素。
② R[0] = R[low] (为了减少数据的移动,将基准元素暂存到 R[0] 中,最后再放入最终位置)
③ high 从后往前移动直到 R[high] < R[0]
④ R[low] = R[high],low++;
⑤ low 从前往后移动直到 R[low] >= R[0]
⑥ R[high] = R[low],high–;
⑦ goto3
⑧ 直到 low == high时,R[low] = R[0] (将基准元素放到最终位置)
概括的说,一次划分就是从数组的两端交替的向中间进行扫描,将小于基准元素值的放到左边,大于等于基准元素值的放到右边,基准元素放在中间。
3.一次划分的具体过程示例
将序列 49、38、65、97、76、13、27、49 一次划分的具体过程为:
1.① low 指向待划分区域首元素,high 指向待划分区域尾元素。
2.② R[0] = R[low]
3.③ high 从后往前移动直到 R[high] < R[0]
4.④ R[low] = R[high],low++
5.⑤ low 从前往后移动直到 R[low] >= R[0]
6.⑥ R[high] = R[low],high–
7.⑦ goto3(③ high 从后往前移动直到 R[high] < R[0])
8.④ R[low] = R[high],low++
9.⑤ low 从前往后移动直到 R[low] >= R[0]
10.⑥ R[high] = R[low],high–
13.⑦ goto3(③ high 从后往前移动直到 R[high] < R[0])
14.⑧ 直到 low == high时,R[low] = R[0]
4.单指针扫描
public void quickSort(int[] arr) {
if (arr != null && arr.length != 0) {
quickSort(arr, 0, arr.length - 1);
}
}
public void quickSort(int[] arr, int left, int right) {
if (left < right) {
int baseNum = arr[left];
int target = left + 1;
for (int i = left + 1; i <= right; i++) {
if (arr[i] <= baseNum) {
swap(arr, i, target);
target++;
}
}
swap(arr, left, target - 1);
quickSort(arr, left, target - 2);
quickSort(arr, target, right);
}
}
public void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
5.双指针扫描
public void quickSort(int[] arr) {
if (arr != null && arr.length != 0) {
quickSort(arr, 0, arr.length - 1);
}
}
public void quickSort(int[] arr, int left, int right) {
if (left >= right) {
return;
}
int baseNum = arr[left];
int low = left;
int high = right;
while (left < right) {
while (left < right && arr[right] >= baseNum) {
right--;
}
if (left < right) {
arr[left++] = arr[right];
}
while (left < right && arr[left] < baseNum) {
left++;
}
if (left < right) {
arr[right--] = arr[left];
}
}
arr[left] = baseNum;
quickSort(arr, low, left - 1);
quickSort(arr, left + 1, high);
}
6.时间复杂度
平均时间复杂度:O(nlog2n)
最坏时间复杂度:O(n2)
最好时间复杂度:O(nlog2n)