快速排序算法介绍
快速排序和归并排序都使用分治法来设计算法,区别在于归并排序把数组分为两个基本等长的子数组,分别排好序之后还要进行归并(Merge)操作,而快速排序拆分子数组的时候显得更有艺术,取一个基准元素,拆分之后基准元素左边的元素都比基准元素小,右边的元素都不小于基准元素,这样只需要分别对两个子数组排序即可,不再像归并排序一样需要归并操作。基准元素的选取对算法的效率影响很大,最好的情况是两个子数组大小基本相当。为简单起见,我们选择最后一个元素,更高级的做法可以先找一个中位数并把中位数与最后一个元素交换,之后再进行相同的操作步骤。拆分是快速排序的核心。快速排序的最坏运行时间是O(n2),但期望的运行时间是O(nlog n)。
Java实现:
package com.edu.byr.sort;
class ArrayUtils {
public static void printArray(int[] array) {
System.out.print("{");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
if (i < array.length - 1) {
System.out.print(", ");
}
}
System.out.println("}");
}
/**
* 交换数组中两个元素位置
* @param array
* @param index1
* @param index2
*/
public static void exchangeElements(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
}
public class QuickSort {
public static void main(String[] args) {
int[] array = {59,46,32,80,46,55,87,43,44,81};
System.out.println("Before sort:");
ArrayUtils.printArray(array);
quickSort(array);
System.out.println("After sort:");
ArrayUtils.printArray(array);
}
public static void quickSort(int[] array) {
subQuickSort(array, 0, array.length - 1);
}
private static void subQuickSort(int[] array, int start, int end) {
//递归条件;数组为空或只有一个元素;停止递归;
if (array == null || (end - start ) < 1) {
return;
}
/**
* partition:对array的start到end区间进行快拍,将最后一个元素作为pivot,左右分别为比其小的、大的元素;
* @return 返回pivot排序后的位置
*/
int part = partition(array, start, end);
if (part == start) {
subQuickSort(array, part + 1, end);
} else if (part == end) {
subQuickSort(array, start, part - 1);
} else {
subQuickSort(array, start, part - 1);
subQuickSort(array, part + 1, end);
}
}
private static int partition(int[] array, int start, int end) {
int pivot = array[end];
int i = start,j = end;
for(;i < end;i ++){
if(array[i] < pivot)
continue;
else{
for(;j > i;j--){
if(array[j] < pivot){
ArrayUtils.exchangeElements(array, i, j);
break;
}
else
continue;
}
}
}
if(j != end && array[j] > pivot){
ArrayUtils.exchangeElements(array, end, j);
return j;
}
if(j != end && array[j] < pivot){
ArrayUtils.exchangeElements(array, end, j+1);
return j+1;
}
return j;
}
}