快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
算法步骤:
1 从数列中挑出一个元素,称为 “基准”(pivot),
2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3 基准的位置将数列分为左右两部分,将左右两部分按照上面的步骤重复(递归调用)即可。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
快速排序详细图解:【坐在马桶上看算法】算法3:最常用的排序——快速排序
算法图示
算法性能
排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 |
快速排序 | O(N*LogN) | O(n2) | O(N*logN) | O(N*logN) | 不稳定 |
Java代码
package com.sort; import java.util.Random; public class Main6 { private static void sort(int[] array, int begin, int end) { if (begin < end) { int left = begin; int right = end; while (left != right) { /** * 选取第一个元素作为标杆,即 array[begin]。先从右边往左边搜索,找到比标杆小的 */ while (array[right] >= array[begin] && right > left) { right--; } /** * 选取第一个元素作为标杆,即 array[begin]。 再从左边往右边搜索,找到比标杆大的 */ while (array[left] <= array[begin] && left < right) { left++; } /** * 交换left(比标杆大,应该在标杆右边)和right(比标杆小,应该在标杆左边)对应的元素 * 这样比标杆大的就在标杆右边,比标杆小的在标杆左边 * * 这里要注意,如果左右没有重合那就交换左右所在的位置的元素,如果左右重合,那就 * 交换这个位置和标杆的位置的元素。 */ if (left < right) { int temp = array[left]; array[left] = array[right]; array[right] = temp; } } /** * 当left == right,说明这个已近遍历结束,这时把标杆和这个位置交换,那么标杆就在数组 * 的中间位置(左边的比标杆小,右边比标杆大) */ int temp = array[left]; array[left] = array[begin]; array[begin] = temp; /** * 继续处理左边的 */ sort(array, begin, left - 1); /** * 继续处理右边的 */ sort(array, right + 1, end); } } /** * 获取指定长度的随机数组 */ public static int[] getRandomArray(int n) { int[] array = new int[n]; Random random = new Random(); for (int i = 0; i < array.length; i++) { array[i] = random.nextInt(500); } return array; } /** * 打印指定数组 */ public static void outputArray(int[] array) { for (int i : array) { System.out.print(i + " "); } System.out.println(""); } public static void main(String[] args) { int[] array = getRandomArray(10); outputArray(array); sort(array, 0, array.length - 1); outputArray(array); } }