即使是同一种算法,也有很多种实现方式。近日看老男孩机构的清华赵博士,一个小伙子写的python快速排序算法,非常非常精巧,比詹青云结辩还精彩。
快速排序百度百科:
快速排序(Quicksort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
百度百科
排序思路百度百科:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
百度百科
代码如下:
def partition(li,left,right):tmp = li[left]while left < right:while left < right and li[right] >= tmp: #从右边找到比tmp小的数right-= 1li[left] = li[right]while left < right and li[left] <= tmp:left += 1li[right] = li[left]li[left] = tmpreturn leftdef quick_sort(li,left,right):if left < right:mid = partition(li,left,right)quick_sort(li,left,mid-1)quick_sort(li,mid+1,right)return lili = [5,7,4,6,3,1,2,9,8]sort_li = quick_sort(li,0,len(li)-1)print(sort_li)
思路分析:
1、第一步“归位”,选中列表第一个元素赋值给tmp,使剩下的元素小于tmp在左边,大于tmp的在右边。首先,从最右边开始遍历,当数值a小于tmp时,tmp原来的位置等于a,然后从左边开始遍历,当数值b大于tmp时,a原来的位置等于b。当左边和右边相遇时,结束遍历,b的位置等于tmp。代码参考文中partition函数,结果是下图“P归位”。
2、“归位”之后,tmp左右边是无序的,排序的思路是把每一个元素当成tmp进行“归位”,也就是递归。代码参考文中quick_sort函数。

递归是一个很抽象过程,画了几张图辅助理解一下。
def partition(a):print(a)a -= 1return adef quick_sort(a):if a > 0:mid = partition(a)print('a')quick_sort(mid)print('b')quick_sort(mid)print('end')
当a=1时
quick_sort(1)输出结果:1abend

图1
蓝色背景是第一次进入quick_sort函数,蓝色背景内的两个白框是分别两次调用自己也就是quick_sort函数。从上往下执行,先输出mid的值,然后是a,b,end
当a=2时
quick_sort(2)
输出结果:

绿色背景是第一次进入quick_sort函数,蓝色背景是两次递归quick_sort函数,蓝色背景内的两个白框是两次递归quick_sort函数。从上往下执行。
当a=3时
quick_sort(3)
输出结果:

其实,递归的过程,特别像内陷的印度水井。从一端走到底,再从底走上来。
印度水井长这样:

许巍的歌应该没人喷~
“
只有青山藏在白云间
蝴蝶自由穿行在清涧
看那晚霞盛开在天边
有一群向西归鸟
谁画出这天地 又画下我和你
让我们的世界绚丽多彩
”




