快速排序
方法描述
1、对一个列表,取第一个数为比较数,然后依次从剩下的列表的左右两端取数,分别和比较数做对比。
2、先从列表右边取数,如果比比较数大,则该数的位置不动,继续从右边取数。反之,则将该数放置在比较数的位置上。此时,右边的位置有空缺。
3、当交换了右边的一个数后,则从列表的左边开始取数(比较数不在参与列表的计数),如果该数比比较数小,则继续在左边下一个取数,当取到比比较数大的数时,则将该数放置到第2步中空出的位置。
4、递归重复第2步,第3步,则最终会出现,一个位置空缺,将比较数放入空缺的位置
代码实现
在代码中给出注释,并结合代码帮助理解上述方法描述
def partition(li, left, right):
"""
:param li: 列表
:param left: 列表最左边的元素位置,即left=0
:param right: 列表最右边的元素位置,即right=len(li)-1
:return: 需要返回一个中间值,即比较数放入的位置
"""
temp = li[left] # 取列表第一个元素作为比较数。 此时,left的位置相当于是空出了。
while left < right:
while left < right and li[right] > temp: # 需要有两个结束条件。1、如果右边的数一直比temp大,则继续循环。2、如果右边指向元素的位置,比左边指向元素的位置还小,也要终止循环。
right -= 1 # 取下一个列表右边的数
li[left] = li[right] # 如果上述循环一直没有比temp小的数,则会一直循环到最左边,则此时,right和left指向的是同一个数。反之,则让right指向的数占据left的位置。这是,右边就空出一个位置了。
while left < right and li[left] < temp: # 同理,left指向的数如果一直比temp更小,则取下一个左边的数。
left += 1
li[right] = li[left] # 同理,如果上述循环一直比temp小,则会一直循环到最右边,这样left和right指向的就是同一个数了。反之,同理。
li[left] = temp # 最后,经过上面两个循环,肯定是left值等于right的值,也就是剩下的temp要存放的位置。
return left # 返回temp存放的位置,方便下一次递归调用。
def quick_sort(li, left, right):
if left < right: # 当列表中有两个及以上的数时,才排序。这也是为递归准备一个终止条件。
mid = partition(li, left, right) # 第一步整理出一个列表,中间的数,比左边的数要大,比右边的数要小,如[2,4,3,1,5,8,7,6,9]。但是,左边或者右边的数是否是按大小排序的不重要,因为后续会继续针对左右两边排序。
quick_sort(li, left, mid-1) # 针对左边的数进行排序
quick_sort(li, mid+1, right) # 针对右边的数进行排序
return li
waitting update
还有一种特殊情况,如列表[9,8,7,6,5,4,3,2,1],这种特殊情况,还需额外增加一步,就是不在令列表的第一个元素为比较数,而是随机取列表中的一个数作为比较数。

浙公网安备 33010602011771号