快速排序的基本思想是:
1、先从数列中取出一个数作为基准数
2、分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边
3、再对左右区间重复第二步,直到各区间只有一个数
上述思想用代码表示:
def quick_sort(data, left, right): if left < right: mid = partion(data, left, right) quick_sort(data, left, mid-1) quick_sort(data, mid+1, right) return data
而关键就是partion函数,如何理解这个函数呢?
看动画:
有这样一组数:
用它演示一下快排思想:
我们想把这组数搞成这个样子(快排的关键):
即:用第一个数(基准数)将整个数组分割成两部分,左边这一部分比第一个数小,右边这一部分比这个数大。
实现的过程如下:
左侧箭头所指的就是我们选择的基准数,右边箭头指的是最后一个数字。
然后用最后一个数字和基准数比较,结果是8比5大,而右边这部分我们本来就要保留大的数,所以接着比较跟8相邻的数字。
下一个是9,和8的情况一样,继续下一个。
下一个是2,2比5小,所以要把2放到左边。
这样的话,空位就跑到右边,所以这次我们要从左边进行比较,即用7跟5比较
由于7比5大,所以要把7放到放到右边空位。
这时候又该从右边比较了,1比5小,所以放到左边。
然后是4,不变
接着是6,放到右边
然后是3,比5小
然后,两个箭头碰上了
这时把5放在这个位置,就完成了整个过程。
理解了这个过程,就可以写partion函数了
def partion(data, left, right): tmp = data[left] while left < right: while left < right and data[right] >= tmp: right -= 1 data[left] = data[right] while left < right and data[left] <= tmp: left += 1 data[right] = data[left] data[left] = tmp return left
完整代码:
import random import time def mytime(func): def inner(*args, **kwargs): t1 = time.time() func(*args, **kwargs) t2 = time.time() print('time costed is {}.'.format(t2 - t1)) return inner @mytime def quick_sort(li): def partion(li, left, right): tmp = li[left] while left != right: while left != right and li[right] >= tmp: right -= 1 else: li[left] = li[right] while left != right and li[left] <= tmp: left += 1 else: li[right] = li[left] li[left] = tmp return left def core(li, left, right): if left < right: mid = partion(li, left, right) core(li, left, mid-1) core(li, mid+1, right) print(li) core(li, 0, len(li)-1) print(li) l = list(range(1000)) random.shuffle(l) quick_sort(l)