简单介绍:
高速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比較。在最坏状况下则须要Ο(n2)次比較,但这样的状况并不常见。其实,高速排序通常明显比其它Ο(n log n) 算法更快,由于它的内部循环(inner loop)能够在大部分的架构上非常有效率地被实现出来。高速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
步骤:
1 ,从数列中挑出一个元素,称为 "基准"
2 ,又一次排序数列,全部元素比基准值小的摆放在基准前面,全部元素比基准值大的摆在基准的后面(同样的数能够到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
3 ,递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。尽管一直递归下去,可是这个算法总会退出,由于在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
复杂度:
数据结构 | 不定 |
---|---|
最差时间复杂度 | ![]() |
最优时间复杂度 | ![]() |
平均时间复杂度 | ![]() |
最差空间复杂度 | 依据实现的方式不同而不同 |
java code:
package com.lxz.sort; import java.util.Arrays; public class QuickSortDemo { // 高速排序在交换元素时会导致相等元素相对位置改变所以是不稳定的 private void quickSort(int[] a, int left, int right) { if (left < right) { int mid = getMid(a, left, right); // int mid = getMid1(a, left, right); quickSort(a, left, mid - 1); quickSort(a, mid + 1, right); } } // 双指针单側向右移动交换。 private int getMid1(int[] a, int left, int right) { int origin = a[left]; int pos = left; for (int j = left + 1; j <= right; j++) { if (a[j] <= origin) { pos++; if (pos != j) {// 假设不等则前面遍历过的元素有小于origin的 int temp = a[j]; a[j] = a[pos]; a[pos] = temp; } } } a[left] = a[pos]; a[pos] = origin; return pos; } // 双指针两端向中间移动交换 private int getMid(int[] a, int left, int right) { int temp = a[left]; while (left < right) {// 这里有等号会导致死循环 while (left < right && temp <= a[right]) // left <= right等号会导致java.lang.ArrayIndexOutOfBoundsException right--; a[left] = a[right]; while (left < right && a[left] <= temp) left++; a[right] = a[left]; } a[left] = temp; return left; } public static void main(String[] args){ QuickSortDemo qsd = new QuickSortDemo(); int b[] = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 5, 4, 62, 99, 98, 54, 56, 17, 18, 23, 34, 15, 35, 25, 53, 51 }; // int b[] = { 8, 9, 6, 3, 4, 5, 2, 1, 7, 2, 12, 11, 15, 1 }; qsd.quickSort(b, 0, b.length - 1); System.out.println(Arrays.toString(b)); } }
參考文献:http://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F