基于比较类型排序性能比较

2022-03-03  本文已影响0人  托贝多尔

from memory_profiler import profile


def quick_sort(l: list):
    length = len(l)
    if length <= 1:
        return l
    p_index = random.randint(0, length - 1)
    p = l[p_index]
    less = -1  # 小于n的区域
    more = length  # 大于n的区域
    index = 0  # 当前索引位置
    while index < more:
        if l[index] < p:
            less += 1  # 小于n区域右移1
            l[index], l[less] = l[less], l[index]
            index += 1  # 当前位置加1
        elif l[index] > p:
            more -= 1  # 大于n区域左移1,当前位置不变
            l[index], l[more] = l[more], l[index]
        else:
            index += 1  # 当前位置加1
    return quick_sort(l[0:less + 1]) + l[less + 1:more] + quick_sort(l[more:])


def quick_sort1(l: list):
    if len(l) <= 1:
        return l
    left, mid, right = [], [], []
    # base_index=random.randint(0,len(l)-1) # 随机选取分组对象,可以最大限度使得当前排序的时间复杂度接近O(nlogn)
    base = l[0]
    for i in l:
        if i < base:
            left.append(i)
        elif i > base:
            right.append(i)
        else:
            mid.append(i)
    return quick_sort(left) + mid + quick_sort(right)


def bubble_sort(l: list):
    for i in range(len(l)):
        for j in range(i + 1, len(l)):
            if l[i] > l[j]:
                l[i], l[j] = l[j], l[i]
    return l


import heapq


def heapify(arr: list, index: int, heap_size: int):
    '''
    堆放,使根节点值最大或最小
    考察index位置的值能否往下沉,较大的孩子如果大于父,父节点往下沉,较大孩子上去,循环向下走,直到走不下去
    heap_size:堆大小,可以灵活使用,控制下沉深度
    '''
    left = index * 2 + 1
    while left < heap_size:
        # 获取两个孩子中最大孩子的索引
        largest = left + 1 if left + 1 < heap_size and arr[left + 1] > arr[left] else left
        # 获取最大孩子跟当前头中较大的值的索引
        largest = largest if arr[largest] > arr[index] else index
        # 比较确认孩子的值是否更大,
        if largest == index:
            break
        #  如果头比孩子小就交换值,继续向下比较
        arr[index], arr[largest] = arr[largest], arr[index]
        index = largest
        left = index * 2 + 1
    return arr


def heapinsert(arr: list, index: int):
    '''
    堆插入
    大根堆:当前节点值跟父节点的值比较,如果当前位置值大于父位置值,则当前位置值跟父位置的值交换,从而实现大根堆
    index:当前位置节点,
    (index-1)//2:父位置节点
    '''
    while index and arr[index] > arr[(index - 1) // 2]:
        arr[index], arr[(index - 1) // 2] = arr[(index - 1) // 2], arr[index]
        index = (index - 1) // 2
    return arr


def heap_sort(l: list):
    print(l)
    h = []
    while l:
        # heapq.heapify(l)
        # h.append(l.pop(0))
        h.append(heapq.heappop(l))
    return h


def heap_sort1(l: list):
    if l is None or len(l) < 2:
        return
    # case_1、先插入数据后排序,可以应对某些动态场景(O(N*logN));一个一个数给
    # for i in range(len(l)):
    #     heapinsert(l, i)

    # case_2、直接heapify排序(O(N*logN));一次给全部数
    i = len(l) - 1
    for _ in range(len(l)):
        heapify(l, i, len(l))
        i -= 1
    heap_size = len(l)
    heap_size -= 1
    l[0], l[heap_size] = l[heap_size], l[0]
    while heap_size > 0:
        heapify(l, 0, heap_size)
        heap_size -= 1
        l[0], l[heap_size] = l[heap_size], l[0]
    return l


@profile(precision=4, stream=open('quick_sort.log', 'w+'))
def test_quick_sort(list_length):
    l = [random.randint(0, 1000) for _ in range(list_length)]
    s = time.time()
    res = quick_sort(l)
    e = time.time()
    print(e - s)


@profile(precision=4, stream=open('quick_sort1.log', 'w+'))
def test_quick_sort1(list_length):
    l = [random.randint(0, 1000) for _ in range(list_length)]
    s = time.time()
    res = quick_sort1(l)
    e = time.time()
    print(e - s)


@profile(precision=4, stream=open('bubble_sort.log', 'w+'))
def test_bubble_sort(list_length):
    l = [random.randint(0, 1000) for _ in range(list_length)]
    s = time.time()
    res = bubble_sort(l)
    e = time.time()
    print(e - s)


@profile(precision=4, stream=open('heap_sort.log', 'w+'))
def test_heap_sort(list_length):
    l = [random.randint(0, 1000) for _ in range(list_length)]
    s = time.time()
    res = heap_sort(l)
    print(res)
    e = time.time()
    print(e - s)


@profile(precision=4, stream=open('heap_sort1.log', 'w+'))
def test_heap_sort1(list_length):
    l = [random.randint(0, 1000) for _ in range(list_length)]
    s = time.time()
    res = heap_sort1(l)
    print(res)
    e = time.time()
    print(e - s)


@profile(precision=4, stream=open('sort.log', 'w+'))
def test_sort(list_length):
    l = [random.randint(0, 1000) for _ in range(list_length)]
    s = time.time()
    l.sort()
    # print(l)
    e = time.time()
    print(e - s)


list_length = 100
# test_quick_sort(list_length)
# test_quick_sort1(list_length)
# test_bubble_sort(list_length)
test_heap_sort(list_length)
# test_heap_sort1(list_length)
# test_sort(list_length)
上一篇下一篇

猜你喜欢

热点阅读