共计 3600 个字符,预计需要花费 9 分钟才能阅读完成。
导读 | 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 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) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
1. 算法步骤
- 从数列中挑出一个元素,称为 “ 基准 ”(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
2. 动图演示
代码实现
JavaScript
实例
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 pivot) {--high;} | |
arr[low] = arr[high]; | |
while (low | |
Python | |
实例 | |
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 | |
Go | |
实例 | |
func quickSort(arr []int) []int {return _quickSort(arr, 0, len(arr)-1) | |
} | |
func _quickSort(arr []int, left, right int) []int { | |
if left | |
C++ | |
实例 | |
// 严蔚敏《数据结构》标准分割函数 | |
Paritition1(int A[], int low, int high) {int pivot = A[low]; | |
while (low = pivot) {--high;} | |
A[low] = A[high]; | |
while (low | |
Java | |
实例 | |
public class QuickSort implements IArraySort { | |
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 | |
PHP | |
实例 | |
function quickSort($arr) | |
{if (count($arr) $middle) | |
$rightArray[] = $arr[$i]; | |
else | |
$leftArray[] = $arr[$i]; | |
} | |
$leftArray = quickSort($leftArray); | |
$leftArray[] = $middle; | |
$rightArray = quickSort($rightArray); | |
return array_merge($leftArray, $rightArray); | |
} | |
C | |
实例 | |
typedef struct _Range {int start, end;} Range; | |
Range new_Range(int s, int e) { | |
Range r; | |
r.start = s; | |
r.end = e; | |
return r; | |
} | |
void swap(int *x, int *y) { | |
int t = *x; | |
*x = *y; | |
*y = t; | |
} | |
void quick_sort(int arr[], const int len) {if (len = range.end) | |
continue; | |
int mid = arr[(range.start + range.end) / 2]; // 選取中間點為基準點 | |
int left = range.start, right = range.end; | |
do {while (arr[left] mid) --right; // 檢測基準點右側是否符合要求 | |
if (left left) r[p++] = new_Range(left, range.end); | |
} | |
} | |
递归法 | |
实例 | |
void swap(int *x, int *y) { | |
int t = *x; | |
*x = *y; | |
*y = t; | |
} | |
void quick_sort_recursive(int arr[], int start, int end) {if (start >= end) | |
return; | |
int mid = arr[end]; | |
int left = start, right = end - 1; | |
while (left = mid && left = arr[end]) | |
swap(&arr[left], &arr[end]); | |
else | |
left++; | |
if (left) | |
quick_sort_recursive(arr, start, left - 1); | |
quick_sort_recursive(arr, left + 1, end); | |
} | |
void quick_sort(int arr[], int len) {quick_sort_recursive(arr, 0, len - 1); | |
} | |
C++ | |
函数法 | |
sort(a,a + n);// 排序 a[0]-a[n-1]的所有数. | |
迭代法 | |
实例 | |
// 参考:http://www.dutor.net/index.php/2011/04/recursive-iterative-quick-sort/ | |
struct Range { | |
int start, end; | |
Range(int s = 0, int e = 0) {start = s, end = e;} | |
}; | |
template // 整數或浮點數皆可使用, 若要使用物件 (class) 時必須設定 "小於"()、"不小於"(>=)的運算子功能 | |
void quick_sort(T arr[], const int len) {if (len = range.end) | |
continue; | |
T mid = arr[range.end]; | |
int left = range.start, right = range.end - 1; | |
while (left = mid && left = arr[range.end]) | |
std::swap(arr[left], arr[range.end]); | |
else | |
left++; | |
r[p++] = Range(range.start, left - 1); | |
r[p++] = Range(left + 1, range.end); | |
} | |
} | |
递归法 | |
实例 | |
template | |
void quick_sort_recursive(T arr[], int start, int end) {if (start >= end) | |
return; | |
T mid = arr[end]; | |
int left = start, right = end - 1; | |
while (left = mid && left = arr[end]) | |
std::swap(arr[left], arr[end]); | |
else | |
left++; | |
quick_sort_recursive(arr, start, left - 1); | |
quick_sort_recursive(arr, left + 1, end); | |
} | |
template // 整數或浮點數皆可使用, 若要使用物件 (class) 時必須設定 "小於"()、"不小於"(>=)的運算子功能 | |
void quick_sort(T arr[], int len) {quick_sort_recursive(arr, 0, len - 1); | |
} | |
阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配 | |
腾讯云新客低至 82 元 / 年,老客户 99 元 / 年 | |
代金券:在阿里云专用满减优惠券 | |
正文完
星哥玩云-微信公众号
