快速排序,顾名思义就是能够将序列快速排序的方法,在同为O(N*logN)的几种排序方法中效率较高的。
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
快速排序的核心思想:
1、先从数组中随机选取一个数作为基准数,一般默认为数组的第一个数,即arr[0];
2、分区,将基准数移到序列中间的某个位置,并实现基准数左边的数小于等于基准数,基准数右边的数大于基准数;
3、将基准数左右两边的序列当成两个新的数组,重复进行1,2步骤,直到所有的分区排序完成。
代码逻辑:
1、对数组{3, 9, 1, 7, 8, 4, 2, 5, 6}进行排序,首先选取基准数arr[0]=3,
2、将这个数组中所有比基准数3大的数放在3的右边,比基准数3小的数放在3的左边;
2.1、从数组右边开始判断,寻找比基准数小的数,这里是arr[6],2比3小,将其放在arr[0]的位置,即arr[0]=arr[6],此时右边开始的下标为6,
然后再从做左边arr[0],就是3后寻找比基准数大的数,这里是arr[1],9比3大,将其放在arr[6]的位置,即arr[6]=arr[1],此时左边开始的下标为1,
然后继续从右边arr[6],就是2后开始寻找比基准数小的数,这里找到了arr[2],1比3小,将其放在arr[1]的位置,即arr[1]=arr[2],此时右边开始的下标为2,
然后再从做左边arr[1],就是9后寻找比基准数大的数,这时候发现右边已经寻找到下标2了,左边继续寻找是1+1已经不小于右边下标2,循环结束,并将基准值3赋值给arr[1+1]=3;
2.2、此时排序是{2, 1, 3, 7, 8, 4,9, 5, 6},实现了基准数3左边的数小于等于基准数,基准数右边的数大于基准数;
2.3、以基准数为中心,分隔数组,将数组{2, 1, 3, 7, 8, 4,9, 5, 6}分成两段,即{2, 1}和{7, 8, 4,9, 5, 6},然后将两数组分别重复之前的操作。
代码实现:
int[] arr3 = {3, 9, 1, 7, 8, 4, 2, 5, 6};
quickSort(arr3, 0, arr3.length - 1);
/**
* 快速排序
*
* {3, 9, 1, 7, 8, 4, 2, 5, 6}
*/
public void quickSort(int arr[], int start, int end) {
if (start < end) {
int flag = getFlagArray(arr, start, end);
quickSort(arr, start, flag - 1);
quickSort(arr, flag + 1, end);
}
}
/**
* 获取调整后基准值对应所在的数组位置
*
* @param arr
* @param start
* @param end
* @return
*/
public int getFlagArray(int[] arr, int start, int end) {
int flag = arr[start];//基准值,默认使用数组的第一个数
int i = start, j = end;
while (i < j) {
//先从右边开始,找出比基准值小的数
while (i < j && arr[j] >= flag) {
j--;
}
if (i < j) {
arr[i] = arr[j];
i++;
}
//从左边开始,找出比基准值大的数
while (i < j && arr[i] < flag) {
i++;
}
if (i < j) {
arr[j] = arr[i];
j--;
}
}
arr[i] = flag;
return i;
}