思考方式
数学家救火法
「数学家救火法」的名字来源于著名的网络段子:
一天,数学家觉得自己已受够了数学,于是他跑到消防队去宣布他想当消防员。
消防队长说:「您看上去不错,可是我得先给您一个测试。」
消防队长带数学家到消防队后院小巷,巷子里有一个货栈,一只消防栓和一卷软管。
消防队长问:「假设货栈起火,您怎么办?」
数学家回答:「我把消防栓接到软管上, 打开水龙,把火浇灭。」
消防队长说:「完全正确。最后一个问题:假设您走进小巷,而货栈没有起火,您怎么办?」
数学家疑惑地思索了半天,终于答道:「我就把货栈点着。」
消防队长大叫起来:「什么?太可怕了,您为什么要把货栈点着?」
数学家回答:「这样我就把问题化简为一个我已经解决过的问题了。」
在数学中,这种思考方式被称为化归。
快速排序的原理
首先在一组数中选取一个基准值(pivot),所有比基准值小的数向左移,比基准值大的数向右移。
3,5,8,1,2,9,4,7,6 待排序的数
3,1,2,4,5,8,9,7,6 选取4为基准值
left为[3,1,2]
right为[5,8,7,6]
我们假设已经知道left和right的排序结果,只需left+[pivot]+right即可得到最终排序的结果。
我们对left和right重复进行上述做法,最终就能得到结果。
代码实现
import random
def quick_sort(numbers):
#定义递归出口
if len(numbers)==1:
return numbers
if len(numbers)==0:
return []
#选取基准值
pivot=random.choice(numbers)
left=[]
right=[]
#遍历待排序列表
for i in numbers:
if i<pivot:
left.append(i)
elif i==pivot:
pass
else:
right.append(i)
Left=[]
Right=[]
Left.extend(quick_sort(left))
Right.extend(quick_sort(right))
return Left+[pivot]+Right
numbers=[3,5,8,1,2,9,4,7,6]
print(quick_sort(numbers))
结果如下
[1, 2, 3, 4, 5, 6, 7, 8, 9]
总结
我们使用了分治的思想,将大问题拆分成小问题,将小问题的解合并起来,就是大问题的答案。
在这个问题中,我们使用了递归的方法,不断调用quick_sort函数处理待排序列表,直到找到递归出口,从而返回上一级递归函数。
OK,That’s it!