简介
快速排序(英语:Quicksort),又称分区交换排序(英语:partition-exchange sort),简称快排,是一种被广泛运用的排序算法。
原理
快速排序的工作原理是通过分治的方式来将一个数组 排序。
快速排序分为三个过程:
1. 将数列划分为两部分(要求保证相对大小关系);
2. 递归到两个子序列中分别进行快速排序;
3. 不用合并,因为此时数列已经完全有序。
和归并排序不同,第一步并不是直接分成前后两个序列,而是在分的过程中要保 证相对大小关系。具体来说,第一步要是要把数列分成两个部分,然后保证前一 个子数列中的数都小于后一个子数列中的数。为了保证平均时间复杂度,一般是 随机选择一个数 m 来当做两个子数列的分界。
之后,维护一前一后两个指针 p 和 q,依次考虑当前的数是否放在了应该放的位置 (前还是后)。如果当前的数没放对,比如说如果后面的指针 q 遇到了一个比 m 小的数,那么可以交换 p 和 q 位置上的数,再把 p 向后移一位。当前的数的位置 全放对后,再移动指针继续处理,直到两个指针相遇。
其实,快速排序没有指定应如何具体实现第一步,不论是选择m的过程还是划分的过程,都有不止一种实现方法。
第三步中的序列已经分别有序且第一个序列中的数都小于第二个数,所以直接拼接起来就好了。
代码实现
struct Range {
int start, end;
Range(int s = 0, int e = 0) { start = s, end = e; }
};
template <typename T>
void quick_sort(T arr[], const int len) {
if (len <= 0) return;
Range r[len];
int p = 0;
r[p++] = Range(0, len - 1);
while (p) {
Range range = r[--p];
if (range.start >= range.end) continue;
T mid = arr[range.end];
int left = range.start, right = range.end - 1;
while (left < right) {
while (arr[left] < mid && left < right) left++;
while (arr[right] >= mid && left < right) right--;
std::swap(arr[left], arr[right]);
}
if (arr[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);
}
}
如有不对,请指出。