美文网首页
堆python实现

堆python实现

作者: 钢筋铁骨 | 来源:发表于2020-04-28 01:05 被阅读0次

    • 堆是一颗完全二叉树
    • 任意节点的左孩子和右孩子比该节点值大时,是小顶堆
      任意节点的左孩子和右孩子比该节点值小时,是大顶堆
    • 堆数次序是是二叉树的层次遍历
    • 堆存储在列表中

    堆的操作
    ①heapify:维护堆状态,也叫堆化。先假设有了一个完整的堆,当根节点变化时,需要重新维护堆状态的动作。
    ②build_heap:建堆,建堆需要从底层建起,找到最后一个节点的父节点x,heapify(x)得到x,x_l_child,x_r_child满足堆结构,再找x-1节点y,heapify(y)得到y,y_l_child,y_r_child满足堆结构,再找x-2,x-3...逆序遍历后,每次都是底层堆已经完整,只有root节点不满足大小,依次heapify后就完成了建堆操作。时间复杂度O(n)
    ③get_top:取堆顶,弹出堆顶后,把堆尾移动到堆顶,然后heapify
    ④insert:插入的数据和父节点比较大小,不满足就交换,然后递归比较。直到满足条件或到走到堆顶

    应用场景
    topK问题,优先级队列

    代码实现

    class MyHeap(object):
        def __init__(self):
            # i从0开始数,建立大顶堆
            # i从1数,father=i//2;    lchild=i*2;   rchild=i*2+1
            # i从0数,father=(i-1)//2;lchild=i*2+1; rchild=i*2+1+1
            self.data_list = []
            self.top = 0
    
        def heap_size(self):
            return len(self.data_list) - 1
    
        def _swap(self, index_a, index_b):
            self.data_list[index_a], self.data_list[index_b] = self.data_list[index_b], self.data_list[index_a]
    
        def _father(self, i):
            return (i - 1) // 2
    
        def _lchild(self, i):
            return i * 2 + 1
    
        def _rchild(self, i):
            return i * 2 + 1 + 1
    
        # 堆的操作:维护堆状态(堆化),堆的top节点发生变化时,重新维护堆的状态
        def heapify(self, root):
            # 如果堆的root不是最大的,那么就和左右孩子中较大的x进行交换,然后top改成x,递归堆化,直到没有满足条件或者到底为止
            if root > self.heap_size():
                return
            left_node = self._lchild(root)
            right_node = self._rchild(root)
            largest_node = root
    
            if left_node <= self.heap_size() and self.data_list[left_node] > self.data_list[largest_node]:
                largest_node = left_node
            if right_node <= self.heap_size() and self.data_list[right_node] > self.data_list[largest_node]:
                largest_node = right_node
            if largest_node != root:
                self._swap(largest_node, root)
                self.heapify(root=largest_node)
    
        # 堆的操作:建堆,找到最后一个node节点的父节点,然后倒着堆化
        # 因为建堆是只能从底下往上建,从上边之间改堆的节点,堆就会塌了
        def build_heap(self, data_list):
            self.data_list = data_list
            last_node = self.heap_size()
            last_node_parent = self._father(last_node)
            for i_node in range(last_node_parent, -1, -1):
                self.heapify(i_node)
    
        # 堆的操作:取堆顶
        def get_heap_top(self):
            if self.heap_size() == 0:
                return None
            res = self.data_list[self.top]
            # 把堆的最后一个元素和堆顶交换,然后重新堆化
            self.data_list[self.top] = self.data_list.pop()
            self.heapify(self.top)
            return res
    
        # 堆的操作:插入操作
        def insert(self, data):
            self.data_list.append(data)
            new_data_index = self.heap_size()
            father_index = self._father(new_data_index)
            while self.data_list[father_index] < data and new_data_index != self.top:
                self._swap(father_index, new_data_index)
                new_data_index = father_index
                father_index = self._father(new_data_index)
    
    
    if __name__ == '__main__':
        data_list = [1, 2, 3, 4, 5, 6, 7]
        s = MyHeap()
        s.build_heap(data_list=data_list)
        print(s.data_list)
        print(s.get_heap_top())
        print(s.get_heap_top())
        print(s.get_heap_top())
        s.insert(data=8)
        print(s.get_heap_top())
    

    相关文章

      网友评论

          本文标题:堆python实现

          本文链接:https://www.haomeiwen.com/subject/poqmwhtx.html