快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:
快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
- function quickSort(arr, left, right) {
- var len = arr.length,
- partitionIndex,
- left = typeof left != 'number' ? 0 : left,
- right = typeof right != 'number' ? len - 1 : right;
-
- if (left < right) {
- partitionIndex = partition(arr, left, right);
- quickSort(arr, left, partitionIndex-1);
- quickSort(arr, partitionIndex+1, right);
- }
- return arr;
- }
-
- function partition(arr, left ,right) { // 分区操作
- var pivot = left, // 设定基准值(pivot)
- index = pivot + 1;
- for (var i = index; i <= right; i++) {
- if (arr[i] < arr[pivot]) {
- swap(arr, i, index);
- index++;
- }
- }
- swap(arr, pivot, index - 1);
- return index-1;
- }
-
- function swap(arr, i, j) {
- var temp = arr[i];
- arr[i] = arr[j];
- arr[j] = temp;
- }
- function partition2(arr, low, high) {
- let pivot = arr[low];
- while (low < high) {
- while (low < high && arr[high] > pivot) {
- --high;
- }
- arr[low] = arr[high];
- while (low < high && arr[low] <= pivot) {
- ++low;
- }
- arr[high] = arr[low];
- }
- arr[low] = pivot;
- return low;
- }
-
- function quickSort2(arr, low, high) {
- if (low < high) {
- let pivot = partition2(arr, low, high);
- quickSort2(arr, low, pivot - 1);
- quickSort2(arr, pivot + 1, high);
- }
- return arr;
- }
-
- def quickSort(arr, left=None, right=None):
- left = 0 if not isinstance(left,(int, float)) else left
- right = len(arr)-1 if not isinstance(right,(int, float)) else right
- if left < right:
- partitionIndex = partition(arr, left, right)
- quickSort(arr, left, partitionIndex-1)
- quickSort(arr, partitionIndex+1, right)
- return arr
-
- def partition(arr, left, right):
- pivot = left
- index = pivot+1
- i = index
- while i <= right:
- if arr[i] < arr[pivot]:
- swap(arr, i, index)
- index+=1
- i+=1
- swap(arr,pivot,index-1)
- return index-1
-
- def swap(arr, i, j):
- arr[i], arr[j] = arr[j], arr[i]
-
- func quickSort(arr []int) []int {
- return _quickSort(arr, 0, len(arr)-1)
- }
-
- func _quickSort(arr []int, left, right int) []int {
- if left < right {
- partitionIndex := partition(arr, left, right)
- _quickSort(arr, left, partitionIndex-1)
- _quickSort(arr, partitionIndex+1, right)
- }
- return arr
- }
-
- func partition(arr []int, left, right int) int {
- pivot := left
- index := pivot + 1
-
- for i := index; i <= right; i++ {
- if arr[i] < arr[pivot] {
- swap(arr, i, index)
- index += 1
- }
- }
- swap(arr, pivot, index-1)
- return index - 1
- }
-
- func swap(arr []int, i, j int) {
- arr[i], arr[j] = arr[j], arr[i]
- }
-
- //严蔚敏《数据结构》标准分割函数
- Paritition1(int A[], int low, int high) {
- int pivot = A[low];
- while (low < high) {
- while (low < high && A[high] >= pivot) {
- --high;
- }
- A[low] = A[high];
- while (low < high && A[low] <= pivot) {
- ++low;
- }
- A[high] = A[low];
- }
- A[low] = pivot;
- return low;
- }
-
- void QuickSort(int A[], int low, int high) //快排母函数
- {
- if (low < high) {
- int pivot = Paritition1(A, low, high);
- QuickSort(A, low, pivot - 1);
- QuickSort(A, pivot + 1, high);
- }
- }
-
- public class QuickSort implements IArraySort {
-
- @Override
- public int[] sort(int[] sourceArray) throws Exception {
- // 对 arr 进行拷贝,不改变参数内容
- int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
-
- return quickSort(arr, 0, arr.length - 1);
- }
-
- private int[] quickSort(int[] arr, int left, int right) {
- if (left < right) {
- int partitionIndex = partition(arr, left, right);
- quickSort(arr, left, partitionIndex - 1);
- quickSort(arr, partitionIndex + 1, right);
- }
- return arr;
- }
-
- private int partition(int[] arr, int left, int right) {
- // 设定基准值(pivot)
- int pivot = left;
- int index = pivot + 1;
- for (int i = index; i <= right; i++) {
- if (arr[i] < arr[pivot]) {
- swap(arr, i, index);
- index++;
- }
- }
- swap(arr, pivot, index - 1);
- return index - 1;
- }
-
- private void swap(int[] arr, int i, int j) {
- int temp = arr[i];
- arr[i] = arr[j];
- arr[j] = temp;
- }
-
- }
-
- function quickSort($arr)
- {
- if (count($arr) <= 1)
- return $arr;
- $middle = $arr[0];
- $leftArray = array();
- $rightArray = array();
-
- for ($i = 1; $i < count($arr); $i++) {
- if ($arr[$i] > $middle)
- $rightArray[] = $arr[$i];
- else
- $leftArray[] = $arr[$i];
- }
- $leftArray = quickSort($leftArray);
- $leftArray[] = $middle;
-
- $rightArray = quickSort($rightArray);
- return array_merge($leftArray, $rightArray);
- }