《漫画算法》--堆排序

251 阅读1分钟

堆排序

二叉堆的特性

  • 最大堆的堆顶是整个堆的最大元素
  • 最小堆的堆顶是整个堆的最小元素

堆排序算法的步骤

  • 把无序数组构建成二叉堆。需要从小到大排序,则构建成最大堆;需要从大到小排序,则构建成最小堆。时间复杂度O(n)
  • 循环删除堆顶元素,替换到二叉堆的末尾,调整堆产生新的堆顶。时间复杂度O(nlogn)
    def heap_sort(array = []):
        # 1.把无序数组构建成最大堆
        for i in range((len(array) - 2) // 2, -1, -1):
            down_adjust(i, len(array),array)
        # 2.循环交换集合尾部元素到堆顶,并调节产生新的堆顶
        for i in range(len(array)-1, 0, -1):
            # 最后一个元素和第一个元素进行交换
            array[i], array[0] = array[0], array[i]
            down_adjust(0, i, array)
    
    
    def down_adjust(parent_index, length, array = []):
        # temp 保留父节点值,用于最后的赋值
        temp = array[parent_index]
        child_index = 2 * parent_index + 1
        while child_index < length:
            # 如果有右孩子,且右孩子的值大于左孩子的值,则定位到右孩子
            if child_index + 1 < length and array[child_index + 1] > array[child_index]:
                child_index += 1
            # 如果父节点的值大于等于任何一个孩子的值,直接跳出
            if temp >= array[child_index]:
                break
            # 无须真正交换,单向赋值即可
            array[parent_index] = array[child_index]
            parent_index = child_index
            child_index = 2* child_index + 1
        array[parent_index] = temp
        
        
    my_array = list([3, 4, 14, 1, 5, 6, 7, 8, 9, 1, -1, 0, 9, 11])
    heap_sort(my_array)
    print(my_array)

  • 堆排序的空间复杂度是O(1),时间复杂度O(nlogn)

堆排序与快速排序对比

堆排序快速排序
平均时间复杂度O(nlogn)O(nlogn)
最坏时间复杂度O(nlogn)O(n2)
平均空间复杂度O(logn)O(1)
是否为稳定排序