216 阅读2分钟

堆(Heap)是一个可以被看成近似完全二叉树的数组。树上的每一个节点对应数组的一个元素。除了最底层外,该树是完全充满的,而且是从左到右填充。

  • 大顶堆:父节点的值大于等于左右孩子的值
  • 小顶堆:父节点的值小于等于左右孩子的值

堆常见的操作:

  • createHeap建堆:把一个乱序的数组变成堆结构的数组
  • insert:把一个数值放入已经是堆结构的数组中,并保持堆结构
  • deleteTop:从大顶堆中取出最大值或从最小堆中取出最小值,并将剩余的数组保持堆结构
  • heapSort:借由createHeap和deleteTop对数组进行排序

堆结构的一个常见应用是建立优先队列(Priority Queue)


class Heap:
    def __init__(self, n, input_list):
        self.n = n  # 元素个数
        self.maxn = 100  # 元素最大个数
        self.heap = [0 for i in range(self.maxn)]
        for i in range(1, n+1):
            self.heap[i] = input_list[i-1]

    def downAdjust(self, low, high):
        '''
        对heap数组在[low,high]范围进行从上到小调整
        low为欲调整节点的数组下标,high一般为堆的最后一个元素的数组下标
        '''
        i = low  # i为欲调整的节点
        j = 2*i  # j为其左孩子
        while j <= high:  # 存在孩子节点
            if j+1 <= high and self.heap[j+1] > self.heap[j]:  # 当右孩子存在且右孩子大于左孩子
                j = j+1  # 此时j为右孩子
            if self.heap[j] > self.heap[i]:  # 孩子中较大值大于父亲节点
                self.heap[i], self.heap[j] = self.heap[j], self.heap[i]  # 交换
                i = j  # 继续向下调整
                j = 2*i
            else:
                break

    def upAdjust(self, low, high):
        i = high  # i为待调整节点
        j = i//2  # j为其父节点
        while j >= low:
            if self.heap[j] < self.heap[i]:
                self.heap[i], self.heap[j] = self.heap[j], self.heap[i]
                i = j
                j = i//2
            else:
                break

    def createHeap(self):
        '''建堆'''
        for i in range(self.n//2, 0, -1):
            self.downAdjust(i, self.n)

    def deleteTop(self):
        '''删除堆顶'''
        self.heap[1] = self.heap[self.n]
        self.n -= 1
        self.downAdjust(1, self.n)

    def insert(self, x):
        '''添加元素'''
        self.n += 1
        self.heap[self.n] = x
        self.upAdjust(1, self.n)

    def heapSort(self):
        self.createHeap()  # 此时堆顶是最大元素
        for i in range(self.n, 0, -1):
            self.heap[1], self.heap[i] = self.heap[i], self.heap[1]
            self.downAdjust(1, i-1)


input_list = [85, 55, 82, 57, 68, 92, 99, 98, 66, 56]
h = Heap(len(input_list), input_list)
h.heapSort()
print(h.heap)