回炉重造了。不得不看好久没碰过的算法。
看维基上快排的代码,有一句,竟然看了一天才明白,我也算是废了。
template<typename T>
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 < 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[end])
std::swap(arr[left], arr[end]);
else
left++;
quick_sort_recursive(arr, start, left - 1);
quick_sort_recursive(arr, left + 1, end);
}
template<typename T>
void quick_sort(T arr[], int len) {
quick_sort_recursive(arr, 0, len - 1);
}
这是C++的实现
其中
if (arr[left] >= arr[end])
std::swap(arr[left], arr[end]);
else
left++;
这一句的条件在什么情况下可能是false?
答案是只有两个元素的时候。
只要进了循环,肯定是true。
就这一句,想了一天才明白,哈哈哈哈,重新审视一下自己。
另外
while (arr[left] < mid && left < right) left++;
感觉这个的条件应该是
while (arr[left] <= mid && left < right) left++;
再来看看伪代码表述
algorithm quicksort(A, lo, hi) is
if lo < hi then
p := partition(A, lo, hi)
quicksort(A, lo, p – 1)
quicksort(A, p + 1, hi)
algorithm partition(A, lo, hi) is
pivot := A[hi]
i := lo - 1
for j := lo to hi - 1 do
if A[j] < pivot then
i := i + 1
swap A[i] with A[j]
if A[hi] < A[i + 1] then
swap A[i + 1] with A[hi]
return i + 1
以及python实现
def quicksort(lst, lo, hi):
if lo < hi:
p = partition(lst, lo, hi)
quicksort(lst, lo, p)
quicksort(lst, p+1, hi)
return
def partition(lst, lo, hi):
pivot = lst[hi-1]
i = lo - 1
for j in range(lo, hi):
if lst[j] < pivot:
i += 1
lst[i], lst[j] = lst[j], lst[i]
if lst[hi-1] < lst[i+1]:
lst[i+1], lst[hi-1] = lst[hi-1], lst[i+1]
return i+1
这种实现巧妙了不少(也反人类了不少,可读性是什么,能吃吗)
注意,这种实现也有那个蜜汁if
if lst[hi-1] < lst[i+1]:
lst[i+1], lst[hi-1] = lst[hi-1], lst[i+1]