一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
前言
今天我们要来聊一聊最为经典的算法——快速排序(Quicksort),快速排序有点跟我们之前讲到的归并排序有点相似,但是解决的思路是有所不同的。
快速排序算法原理
快速排序的主体思想是这样的:我们需要对一个数组中的下标p到r之间的一组数据的话,我们选择p到r之间的任意一个数据作为pivot(分区点)。然后遍历p到r之间的数据,将小于pivot的数放到左边,将大于pivot的数据放到右边。将pivot放到中间。经过这个流程后,p到r之间的数据就被划分成三个部分,p到q-1小于pivot,中间是pivot。随后的q+1到r之间的都是大于pivot的。因为快速排序也是基于分治和递归的处理思想的。只要我们分区分到区间长度只有1的时候,那么就代表区间都是有序的了。也就是排序完成了。由此可以得到我们的递归公式是如下所示的:
quick_sort(p…r) = quick_sort(p…q-1) + quick_sort(q+1, r)
p >= r
由递归公式的话,我们可以得到对应的代码实现
public void quickSort(int arr[], int begin, int end) {
if (begin < end) {
int partitionIndex = partition(arr, begin, end);
quickSort(arr, begin, partitionIndex-1);
quickSort(arr, partitionIndex+1, end);
}
}
private int partition(int arr[], int begin, int end) {
int pivot = arr[end];
int i = (begin-1);
for (int j = begin; j < end; j++) {
if (arr[j] <= pivot) {
i++;
int swapTemp = arr[i];
arr[i] = arr[j];
arr[j] = swapTemp;
}
}
int swapTemp = arr[i+1];
arr[i+1] = arr[end];
arr[end] = swapTemp;
return i+1;
}
如果我们不考虑内存消耗的话,可以额外的采用两个左右数组来进行分区的,但是这样快速排序就不是原地算法了,它所具备的优势就不存在了。所以采用原地分区的算法的快速排序性能才会更好
总结
快速排序是非常经典的算法之一,值得我们去好好学习掌握的。