Loading

数据结构与算法(四) --- 排序

1. 堆排序

def heap_sort(li):
    def _heapfly(li):
        start = (len(li)) // 2 - 1 # 获取最后一个叶子节点的父节点
        for nod in range(start, -1, -1):
            left = 2 * nod + 1
            right = min(left + 1, len(li) - 1)
            temp = left if li[left] > li[right] else right
            if li[temp] > li[nod]:
                li[temp], li[nod] = li[nod], li[temp]
        return li

    result = []
    for i in range(len(li)):
        li = _heapfly(li)
        result.append(li.pop(0))
    return result

if __name__ == '__main__':
    l = [3, 1, 4, 9, 6, 7, 5, 8, 2, 10, 14]
    print(heap_sort(l))

2. 归并排序

def merge_sort(li):
    def _merge(a, b):
        result = []
        while a and b:
            temp = a.pop(0) if a[0] < b[0] else b.pop(0)
            result.append(temp)
        result.extend(a if a else b)
        return result

    length = len(li)
    if length == 1:
        return li
    else:
        mid = int(length/2)
        l = li[:mid]
        r = li[mid:]
        return _merge(merge_sort(l), merge_sort(r) )

if __name__ == '__main__':
    print(merge_sort([1, 3, 5, 2, 7, 9, -1]))

3. 快速排序

1. 递归

def quicksort1(nums):
    if len(nums) <= 1:
        return nums

    # 左子数组
    less = []
    # 右子数组
    greater = []
    # 基准数
    base = nums.pop()

    # 对原数组进行划分
    for x in nums:
        if x < base:
            less.append(x)
        else:
            greater.append(x)

    # 递归调用
    return quicksort1(less) + [base] + quicksort1(greater)

2. 前后指针

此方法是逐个和最后一个比较,保留划分点指针,遍历一遍后交换。
另外, 相比递归, 维护一个栈或者队列, 不断往里放入需要排序的子序列(头, 尾), 直到栈/队列为空.


def quite_sort(li):
    left = 0
    right = len(li)-1
    stack = [(left, right)]
    while stack:
        print(f'栈数据->{stack}')
        # print(f'栈数据->{stack}')
        left, right = stack.pop() 
        
        # 这里有三种思路, 埋坑,左右指针,前后指针
        curr = _deal_with_1(li, left, right)

        if curr > left+1:
            stack.append((left, curr))
        if right > curr+1:                                             
            stack.append( (curr+1, right) )
    return li

# 前后指针
def _deal_with_1(li, left, right):
    curr = left
    for i in range(left, right):
        if li[i] < li[right-1]:
            li[i], li[curr] = li[curr], li[i]
            curr += 1
    else: 
        li[curr], li[right-1] = li[right-1], li[curr]
    return curr



if __name__ == "__main__":
    array = [-1, 11, 4, 2, 3, 9, 5]
    print(quite_sort(array))

posted @ 2019-10-11 16:49  Geoffrey_one  阅读(158)  评论(0编辑  收藏  举报
/*
*/