普通的快排我们可以选择数组首元素或尾元素作为pivot,代码如下
def quick_sort(nums):
if not nums:
return []
else:
div=nums[0]
left=quick_sort([l for l in nums[1:] if l<=div])
right=quick_sort([r for r in nums[1:] if r>div])
return left+[div]+right
若现在数组是一有序数组,则每次划分只能排序一个数。效率很低,时间复杂度为。输入数据很大时,效率很低。因此我们需要改进pivot的选取方式。常见的做法是三数取中。即数组首,尾,中间位置三数中的中位数作为pivot。这样可以消除待排序数组顺序不好的情况。代码如下
def quick_sort2(nums):
if not nums:
return []
else:
lst=[nums[0],nums[-1],nums[len(nums)/2]]
div=sorted(lst)[1]
index=nums.index(div)
left=quick_sort2([l for l in (nums[:index]+nums[index+1:]) if l<=div])
right=quick_sort2([r for r in (nums[:index]+nums[index+1:]) if r>div])
return left+[div]+right
比较两种算法的时间。定义一个10000大小的有序数组。
nums1=[i for i in range(int(1e4))]
nums2=[random.randint(0,int(1e4)) for i in range(int(1e4))]
start=time()
quick_sort(nums1)
end=time()
print 'quick_sort time: %fs' % (end-start)
start=time()
quick_sort2(nums1)
end=time()
print 'quick_sort2 time: %fs' % (end-start)
输出结果如下:
可以看出效果还是很明显的。