快速排序


快速排序

思想

给定一个数组或者一个列表,通过提取出第一个列表中的值,将它‘归位’,归位的概念就是归位之后,左边的数都比他小,右边的数都比他大,以至于归位之后这个数是不会再调整位置了。

方法

先将左边第一个值提取出来,将它归位,归位的方法是将第一个值存储起来,然后先从右边向左遍历,匹配将要归位的数值是否比它大,如果比它大则继续遍历,如果比它小,则将该值赋值给将要归位的原位置(原因:该位置如果归位之后是为空),赋值之后,再反过来遍历,自左向右遍历只不过从归位后面的那位值开始遍历,匹配是否比归位值小,如果小,就继续移动指针,直到匹配到比归位值大的值,然后赋值给上次移到左边来的值原位置,反复循环的过程,直到左右指针相遇,意味着所有的值遍历完成,然后将归位的值放在左右指针相遇的位置,再次提取出列表的值以此循环。

以上仅为一个归位的函数,而我们需要通过一个框架去重复调用这个函数,实现整个无序列表的值都归位,

框架代码如下:

def quick_sort(li, left, right):    # 传入列表,左边指针位置,右边指针位置
    if left < right :    # 判断指针是否相遇
        min = quick_min(li, left, right)    # 寻找归位的值
        quick_sort(li, left, min-1)    # 移动右边递减
        quick_sort(li, min+1, right)    # 移动左边指针

quick_min函数就是归位函数,代码如下:

def quick_min(li, left, right):
    tmp = li[left]    # 临时存储将要归位的值
    while left < right:    # 判断指针是否相遇
        while left < right and li[right] >= tmp:    # 从右边遍历寻找是否有比tmp的值小的值
            right -= 1    # 如果比tmp值大则移动右边指针
        li[left] = li[right]    # 如果找到比tmp小的值则赋值到左边
        while left < right and li[left] <= tmp:    # 从左边遍历寻找是否有比tmp值大的指
            left += 1    # 如果比tmp值小则移动指针
        li[right] = li[left]    # 如果比tmp值大则赋值到右边刚赋值到左边的原位置
    li[left] = tmp    # 指针相遇之后将tmp值赋值到指针相遇处,完成归位
    return left    # 返回left的位置,因为这是归位之后的位置,以此处可以将两边分为两段无序列表

全部代码:

import random

def quick_min(li, left, right):
    tmp = li[left]
    while left < right:
        while left < right and li[right] >= tmp:
            right -= 1
        li[left] = li[right]
        while left < right and li[left] <= tmp:
            left += 1
        li[right] = li[left]
    li[left] = tmp
    return left

def quick_sort(li, left, right):
    if left < right :
        min = quick_min(li, left, right)
        quick_sort(li, left, min-1)
        quick_sort(li, min+1, right)

def test(li):
    quick_sort(li, 0, len(li) - 1)

li = list(range(100000))
random.shuffle(li)
print(li)
test(li)
print(li)