引
quickSort堪称是排序算法中的经典之作。实现代码短小,但速度非凡。就短短2、30行代码我至今才一窥堂奥,感谢《啊哈,算法!》的启发。
快速排序的基本思路是分治。选择一个中间数,将数列分为比之小、大的两部分,进而对分割的自数列分别排序,直到子数列只有一个元素为止,整个排序完成。
分割数列
首先需要选择一个数将数列分开,左侧的比之小,右侧的比之大。这个数可以选择第一个元素。
版本一
def makeItemMidInSeq(s, i, end):
"""
set item i in middle of seq
let the left items < s[i], right > s[i]
"""
# set j = i + 1
j = i + 1
# until j == end stop cmp
while j < end:
if s[i] > s[j]:
# move s[j] to i pos
for x in xrange(j, i, -1):
tmp = s[x]
s[x] = s[x - 1]
s[x - 1] = tmp
# move s[i] to next
i += 1
# move s[j] to next
j += 1
return i
版本二
def splitSeqTwoParts(s, x):
"""
将序列s按数值x排成两部分,前半部分小于x,后半部分大于x
并返回分界位置,即最后一个小于x的值位置
"""
# 指标i从开头,j从末尾依次遍历序列,i>=j时遍历停止
i = 0
j = len(s) - 1
while i < j:
# 如果s[i]>x, s[j]<x,i,j交换, i,j继续移动
if s[i] > x and s[j] < x:
tmp = s[j]
s[j] = s[i]
s[i] = tmp
i += 1
j -= 1
# 如果s[i]<x, s[j]<x, j不动,i继续向后移动一位
elif s[i] < x and s[j] < x:
i += 1
# 如果s[i]>x, s[j]>x, i不动,j继续向前移动一位
elif s[i] > x and s[j] > x:
j -= 1
else:
i += 1
j -= 1
递归分割
将分割出的子数列继续分割,直到数列只剩一个数为止,排序全部完成。