堆--优先队列 (Python)最大堆,最小堆 create, pop, push

1.完全二叉树的一个父节点编号为k,那么他的左二子的编号为2*k+1,右二子节点的编号为2*k+2

2.如果已知儿子(左儿子或者右儿子)的编号为x,那么他的父节点的编号为(x-1)//2(取整除,就是计算机里的/)

3.最小堆是所有的父节点都比他的子节点小,最大堆是所有的父节点都比他的子节点大

4.像这样支持插入元素和寻找元素(最大值和最小值)的数据结构成为优先队列,如果使用普通队列,那么寻找最大元素就需要枚举整个队列,时间复杂度为O(n),时间复杂度比较高,如果是已经排好序的数组,那么插入一个元素需要移动大量的数据,时间复杂度依旧很高,而堆就是一种优先队列的实现,可以很好地解决这两种操作

5.堆经常被用来求一个数列中第K大的数,只需要建立一个大小为K的最小堆,堆顶就是第K大的数(举个例子,假设有事十个数,要求第3大的数,将前三个数建成最小堆,然后从第四个数开始,与堆顶元素比较,如果比堆顶元素大,则舍弃当前堆顶元素,而将这个新数作为堆顶,然后堆顶开始向下调整,如果比堆顶元素小,则不进入堆),同理如果求第K小的数,那么就建一个最大堆,这种方法的时间复杂度为O(NlogK)

6.创建堆的过程是,要么是对一个已经存在的数组进行调整顺序然后,调整成一个合法的heap。要么是往一个heap里面添加元素。

堆 - 讲解很好的博客,但是没有给出代码

class Heap:
    def __init__(self, heap):
        self.heap = heap

    def shift_down(self, i):
        finished = False
        i_min = i
        child_i = i_min * 2 + 1
        length = len(self.heap) - 1

        while child_i <= length and not finished:
            if self.heap[child_i] < self.heap[i]:
                i_min = child_i

            child_i += 1
            if child_i <= length and self.heap[i_min] > self.heap[child_i]:
                i_min = child_i

            if i_min != i:
                self.heap[i], self.heap[i_min] = self.heap[i_min], self.heap[i]
                i = i_min
                child_i = i * 2 + 1
            else:
                finished = True

    def shift_up(self, i):
        finished = False
        f_i = (i - 1) // 2

        while f_i >= 0 and not finished:
            if self.heap[f_i] > self.heap[i]:
                self.heap[i], self.heap[f_i] = self.heap[f_i], self.heap[i]
                i = f_i
                f_i = (i - 1) // 2
            else:
                finished = True

    def create(self):
        i = (len(self.heap) - 2) // 2
        while i >= 0:
            self.shift_down(i)
            i -= 1
    def pop(self):
        val = self.heap[0]
        length = len(self.heap) - 1
        self.heap[0], self.heap[length] = self.heap[length], self.heap[0]
        self.heap.pop()
        self.shift_down(0)
        return val

    def push(self, val):
        self.heap.append(val)
        self.shift_up(len(self.heap) - 1)

    def print(self):
        for val in self.heap:
            print(val)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值