介绍
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
步骤
- 从数列中挑出一个元素,称为”基准”(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
分析
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
最好和最坏情况
- 最好的情况是枢纽元选取得当,每次都能均匀的划分序列。 时间复杂度O(nlogn);
- 最坏情况是枢纽元为最大或者最小数字,那么所有数都划分到一个序列去了 时间复杂度为O(n^2).
代码实现
/**
* Created by lysongzi on 16/3/2.
* 快速排序
*/
public class QuickSort {
static int temp;
public static void sort(int[] arr){
quick_sort_recursive(arr, 0, arr.length - 1);
}
private static void quick_sort_recursive(int[] arr, int start, int end){
if (start >= end)
return;
int pivot = arr[end];
int left = start;
int right = end - 1;
while (left < right){
//左边找一个比权值大的数
while (arr[left] < pivot && left < right)
left++;
//右边找一个比权值小的数
while (arr[right] >= pivot && right > left)
right--;
//交换找到的数对
swap(arr, left, right);
}
if (arr[left] >= arr[end])
swap(arr, left, end);
else
left++;
quick_sort_recursive(arr, start, left - 1);
quick_sort_recursive(arr, left + 1, end);
}
private static void swap(int[] arr, int lhs, int rhs){
temp = arr[lhs];
arr[lhs] = arr[rhs];
arr[rhs] = temp;
}
}