关于快速排序

回炉重造了。不得不看好久没碰过的算法。

看维基上快排的代码,有一句,竟然看了一天才明白,我也算是废了。

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]

  

转载于:https://www.cnblogs.com/gagugagu/p/7642646.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值