美文网首页
用堆来实现一个有界优先队列

用堆来实现一个有界优先队列

作者: yxwithu | 来源:发表于2017-11-26 13:22 被阅读0次

用堆来实现一个有界有点队列有两个步骤,以大顶堆为例,在加入元素时:

  1. 堆不满时(未到达界限),每加入一个元素都需要一次从尾到头的最大堆调整;
  2. 堆满时,需要将大顶堆堆顶值置换为队列尾的值,并进行一次从头到尾的最大堆调整,再将新元素加入到队尾,进行一次从尾到头的最大堆调整(步骤1)。

需要注意的是:无论是加入一个新元素或者弹出堆顶,都需要一次调整

实现代码:

class BoundedPriorityQueue:
    """优先对列(max heap)及相关实现函数"""
    def __init__(self, k):
        self.heap=[]
        self.k = k
    
    def items(self):
        return self.heap
    
    def parent(self,index):
        """返回父节点的index"""
        return int(index/2)
    
    def left_child(self, index):
        return 2 * index + 1
    
    def right_child(self, index):
        return 2 *index + 2
    
    def _dist(self, index):
        """返回index对应的值"""
        return self.heap[index]
    
    def max_heapify(self, index):
        """负责维护最大堆,使当前节点的所有子节点均小于该父节点"""
        left_index = self.left_child(index)
        right_index = self.right_child(index)
        
        largest = index
        if left_index < len(self.heap) and self._dist[left_index] > self._dist[index]:
            largest = left_index
        if right_index < len(self.heap) and self._dist[right_index] > self._dist(largest):
            largest = right_index
        if largest != index:
            self.heap[index], self.heap[largest] = self.heap[largest], self.heap[index]
            self.max_heapify(largest)
            
    def propagate_up(self, index):
        """在index位置添加新元素后,通过不断和父节点比较并交换,维持最大堆的特性,
        保持堆中父节点的值永远大于子节点"""
        while index != 0 and self._dist(self.parent(index)) < self._dist(index):
            self.heap[index], self.heap[self.parent(index)] = self.heap[self.parent(index)], self.heap[index]
            index = self.parent(index)
    
    def add(self, obj):
        """如果当前值小于优先队列中的最大值,则将obj添加入队列,
        如果队列已满,则移除最大值再添加,这时原队列中的最大值将被obj取代"""
        size = self.size()
        if size == self.k:
            max_elem = self.max()
            if obj[1] < max_elem:
                self.extract_max()
                self.heap_append(obj)
        else:
            self.heap_append(obj)
            
    def heap_append(self, obj):
        """向队列中添加一个obj"""
        self.heap.append(obj)
        self.propagate_up(self.size() - 1) 
    
    def size(self):
        return len(self.heap)

    def max(self):
        return self.heap[0][4]
    
    def extract_max(self):
        """将最大值从队列中移除,同时对新队列排序"""
        max = self.heap[0]
        data = self.heap.pop()
        if len(self.heap) > 0:
            self.heap[0] = data
            sele.max_heapify(0)
        return max

相关文章

  • 用堆来实现一个有界优先队列

    用堆来实现一个有界有点队列有两个步骤,以大顶堆为例,在加入元素时: 堆不满时(未到达界限),每加入一个元素都需要一...

  • priority_queue

    priority_queue 优先队列,其底层是用堆来实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那...

  • priority_queue

    priority_queue又称为优先队列,其底层是用堆来进行实现的。在优先队列中,队首元素一定是当前队列中优先级...

  • [数据结构与算法-iOS 实现]优先级队列

    优先级队列 可以利用二叉堆来实现优先级队列,比如我们用大顶堆,堆顶为我们的最大元素,可以理解为优先级最高的元素,我...

  • 数据结构——优先队列和堆

    目录 1、优先队列 1.1、什么是优先队列 1.2、优先队列的实现 2、堆 2.1、什么是堆 2.2、堆的类型 2...

  • 算法面试通关-堆栈&队列《三》

    队列 FIFO 栈 FILO 优先队列用堆实现或者二叉查找树 0020-有效的括号0232-用栈实现队列0225-...

  • iOS 数据结构之有界优先级队列

    有界优先级队列 是一个有元素最大限制的优先级队列。如果一个新的元素插入到有界优先级队列中,但是容量已经最大了,那么...

  • 看图说话数据结构之二项队列(优先队列)——原理解析

    数据结构之二叉堆(优先队列)——原理解析,数据结构之二叉堆(优先队列)——java实现,数据结构之左式堆(优先队列...

  • PriorityQueue源码学习

    PriorityQueue源码学习 使用堆来实现一个优先级队列,comapreTo()比较最小的那个放在堆顶,每次...

  • 优先级队列

    一、定义 优先级队列有很多种实现方式。其中使用“堆”来实现“优先队列”是最常见的,堆的底层是完全二叉树的形式。 上...

网友评论

      本文标题:用堆来实现一个有界优先队列

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