快速排序也是面试中经常问到的算法,人人都应该掌握。快速排序是对冒泡排序的改进,它的基本思想是:采用分而治之的思想,选取一个基准,一趟排序后把数据分成两部分,一部分都比基准小,另一部分都比基准点大,然后再对这两部分分别进行上述的操作,直到整个序列有序。快速排序因为数据的交换是跳跃的,所以速度比只和相邻数据交换的冒泡排序要快,平均时间复杂度为O(NlogN)。
该算法主要有两种实现方法:递归和非递归。
1.递归的实现方法:
def quick_sort(array):
if len(array) < 2:
return array
basevalue = array[0]
less = []
great = []
equal = [basevalue]
for i in array[1:]:
if i < basevalue:
less.append(i)
elif i > basevalue:
great.append(i)
else:
equal.append(i)
return quick_sort(less) + equal + quick_sort(great)
if __name__ == '__main__':
array = [5, 8, 7, 6, 5, 4, 0, 3, 2, 1, 9]
sorted = quick_sort(array)
print(sorted)
结果为:
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9]
2.非递归的实现利用了栈来完成,使用栈来记录每次分治数据的边界,将待处理数据的右边界索引、左边边界索引入栈,判断栈是否为空,如果不为空,取出两个栈元素,处理该两个栈元素范围内的数据:数据进行分区,使左边分区都小于等于基准值,右边分区都大于等于基准值,返回基准值的索引index。判断index-1>左边界索引,将index和左边界索引入栈。判断index+1<右边界索引,将右边界索引和index入栈。然后重复这个过程,代码如下:
def quick_sort_stack(arr):
'''''
模拟栈操作实现非递归的快速排序
'''
if len(arr) < 2:
return arr
stack = []
stack.append(len(arr) - 1)
stack.append(0)
while stack:
l = stack.pop()
r = stack.pop()
index = partition(arr, l, r)
if l < index - 1:
stack.append(index - 1)
stack.append(l)
if r > index + 1:
stack.append(r)
stack.append(index + 1)
def partition(arr, start, end):
# 分区操作,返回基准线下标
pivot = arr[start]
while start < end:
while start < end and arr[end] >= pivot:
end -= 1
arr[start] = arr[end]
while start < end and arr[start] <= pivot:
start += 1
arr[end] = arr[start]
arr[start] = pivot
return start
if __name__ == '__main__':
array = [5, 8, 7, 6, 5, 4, 0, 3, 2, 1, 9]
quick_sort_stack(array)
print(array)
结果为:
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9]