快速排序

方法描述

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],这种特殊情况,还需额外增加一步,就是不在令列表的第一个元素为比较数,而是随机取列表中的一个数作为比较数

原理后续说明

posted @ 2022-04-04 15:34  尘。哀  阅读(58)  评论(0)    收藏  举报