关于快速排序
回炉重造了。不得不看好久没碰过的算法。
看维基上快排的代码,有一句,竟然看了一天才明白,我也算是废了。
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]