快速排序(Quick Sort)
Posted 码畜笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速排序(Quick Sort)相关的知识,希望对你有一定的参考价值。
快速排序基本思想:
每次从当前数组中选择一个元素,以这个元素为基点,将它挪到它左右都排好序后应该在的位置,这样基点左边的数都比基点小,而基点右边的数都比基点大.
比如:
int array[] = {10, 9, 8, 7, 6, 55, 11};
将10作为基点,挪到他该在的位置,左边比它小,右边比他大:
int array[] = {9, 8, 7, 6,10, 55, 11};
之后对小于10的数组和大于10的数组分别使用快速排序的思路进行排序,逐渐递归下去.
核心问题:
如何将基点放到它该在的位置?
Partition,也就是将数组分为两个部分.
实现思路:
通常将数组中的第一个元素作为基点v(下标为l),遍历右边所有没有被访问的元素,在遍历的过程中,逐渐整理,让整个数组一部分小于基点,一部分大于基点.在这个过程中,需要记录大于基点和小于基点的分界点(下标为j)和当前访问的元素e(下标为i).
举例:10为基点v,9,8,7都小于10,j就是7;55,11都大于10,假设我们现在正在访问e就是4
int array[] = {10, 9, 8, 7, 55, 11, 4, 12};
这样数组就形成了arr[l+1,....,j]<v和v<arr[j+1,......,i-1]
那么当前的元素要怎样变化,使得数组的性质仍然保持不变?我们现在访问4这个元素,那么就需要对4进行比对,4<10,于是放入arr[l+1,....,j]中,j++就可以
此时,9,8,7,4在这个区间arr[l+1,....,j]
55,11在这个区间arr[j+1,......,i-1]
int array[] = {10, 9, 8, 7, 4, 55, 11,12};
执行下一步e++,到了12,12>10,12就直接放入arr[j+1,......,i-1]区间内,i++继续下一步就行
现在遍历完成了,数组就是这个样子:
v=10,arr[l+1,....,j]中是9,8,7,4,arr[j+1,......,i-1]中是55,11,12
int array[] = {10, 9, 8, 7, 4, 55, 11,12};
最后将l和j对应的元素交换位置:
int array[] = {7, 9, 8, 4, 10, 55, 11,12};
代码:
public static void main(String[] args) {
int array[] = {10, 9, 8, 7, 55, 11, 4, 12};
quickSort(array);
System.out.println(Arrays.toString(array));
}
private static void quickSort(int[] arr) {
int n = arr.length;
quick(arr, 0, n - 1);
}
//对arr[l...r]进行快速排序
private static void quick(int arr[], int l, int r) {
//对递归到底进行处理
if (l >= r) {
return;
}
//对当前数组进行partition的操作,返回一个索引值
int p = partition(arr, l, r);
//递归的快速排序
quick(arr, l, p - 1);
quick(arr, p + 1, r);
}
//arr[l...r]部分进行partition的操作
//返回P,使得arr[l....p-1]<arr[p];arr[p+1....r]>arr[p]
private static int partition(int[] arr, int l, int r) {
//arr[l+1....j]<v;arr[j+1....i)>v
int v = arr[l];
int j = l;
for (int i = l + 1; i <= r; i++) {
if (arr[i] < v) {
swap(arr, j + 1, i);
j++;
}
}
swap(arr, l, j);
return j;
}
private static void swap(int[] arr, int a, int b) {
int t = arr[a];
arr[a] = arr[b];
arr[b] = t;
}
结果:
[4, 7, 8, 9, 10, 11, 12, 55]
以上是关于快速排序(Quick Sort)的主要内容,如果未能解决你的问题,请参考以下文章