快速排序

"""
分治法:
    归并排序:
        分解原问题为若干个子问题,解决这些子问题
        递归求解子问题
        合并子问题的解,成为原问题的解
"""
'''快速排序非常重要,很多内置排序都使用这个算法'''


def quick_sort(seq):
    if len(seq) <= 1:  # 设置递归出口
        return seq
        
    povit_index = 0
    povit = seq[povit_index]
    left_part = [i for i in seq[povit_index+1:] if i <= povit]  # 需要额外空间
    right_part = [i for i in seq[povit_index+1:] if i > povit]
    # 每次递归都是遍历了两次全域数组
    
    return quick_sort(left_part) + [povit] + quick_sort(right_part)
    
# def test_sort():
    # import random
    # seq = list(range(10))
    # random.shuffle(seq)
    # assert quick_sort(seq) == sorted(seq)
    # assert 0
    
# ##############################################################################
# 不使用额外内存

def partition(array, start, end):
    povit_index = start  # 第一个元素作为基准
    
    # 不断收敛指针
    povit = array[povit_index]
    i = povit_index+1
    j = end-1
    while True:
        while i <= j and array[i] < povit:
            i += 1
        while j >= i and array[j] >= povit:
            j -= 1
            
        if i > j:
            break
        else:
            array[i], array[j] = array[j], array[i]  # 边界条件非常容易出错
            
    array[povit_index], array[j] = array[j], array[povit_index]
    return j

# def test_partition():
    # l = [4, 1, 2, 8]
    # assert partition(l, 0, len(l)) == 2
    # l = [1, 2, 3, 4]
    # assert partition(l, 0, len(l)) == 0
    # l = [4, 3, 2, 1]
    # assert partition(l, 0, len(l)) == 3
    # assert 0
    # pass
    
def quick_sort_inplace(array, beg, end):
    if beg < end:
        pivot = partition(array, beg, end)
        quick_sort_inplace(array, beg, pivot)
        quick_sort_inplace(array, pivot+1, end)
        
def test_quick_sort_inplace():
    import random
    seq = list(range(10))
    random.shuffle(seq)
    print(seq)
    # assert quick_sort_inplace(seq, 0, len(seq)) == sorted(seq)
    quick_sort_inplace(seq, 0, len(seq))
    print(seq)
    assert 0
    
    pass
    

 

posted @ 2020-05-05 02:46  SBJBA  阅读(91)  评论(0)    收藏  举报