快速排序实现:
快速排序也是使用分治思想将数组进行划分,然后对子数组进行排序,主要排序思路是,对数组选取一个基准数pivot, 小于pivot的放到数组左边,大于pivot的放到右边,看图(r为基准数),
我们子数组的排序称为partition(划分), 目的就是将数组分成两组,小于r一组,大于r一组,r放在中间需要返回(这样我们才能继续对子数组递归partition), partition实现:
/**
* 对数组进行划分
* @param arr 待分区数组
* @param p 数组起始索引
* @param r 数组结束索引
* @return 划分完后,基准数所在索引
*/
private static int partition(int[] arr, int p, int r) {
// 选取最后一个元素为基准数
int pivot = arr[r];
int i = p - 1;
int temp;
for (int j=p; j <= r-1; j++){
if (arr[j] <= pivot){
i++;
//交换 arr[i] <--> arr[j]
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
//将基准数放到中间 arr[i+1] <--> arr[r]
temp = arr[i+1];
arr[i+1] = arr[r];
arr[r] = temp;
return i+1;
}
看一个实例图partition过程:
完成一个数组partition后,我们还要递归使用partition:
/**
* 快速排序实现
* @param arr 待排序数组
* @param p 数组起始索引
* @param r 数组结束索引
*/
private static void quickSort(int[] arr, int p, int r) {
if (p < r){
int q = partition(arr, p, r);
quickSort(arr, p, q-1);
quickSort(arr, q+1, r);
}
}
测试用例:
int[] arr = new int[]{2, 8, 7, 1, 3, 5, 6, 4};
quickSort(arr, 0, arr.length-1);
快速排序时间复杂度为nlgn.