Algorithm 实现优先级队列算法

Algorithm 实现优先级队列算法,algorithm,data-structures,heap,Algorithm,Data Structures,Heap,这是我的PriorityQueue算法的实现。我有一种感觉,我的弹出功能是错误的。但我不确定到底哪里错了。我已经多次检查我的逻辑哪里出错了,但它似乎完全正确(使用CLRS伪代码检查) 类优先级队列: “”“基于数组的优先级队列实现。”“” 定义初始化(自): “”“初始优先级队列为空。”“” self.queue=[] self.min_索引=无 def父级(自我,i): 返回整数(i/2) def left(self,i): 返回2*i+1 定义权限(self,i): 返回2*i+2 def

这是我的PriorityQueue算法的实现。我有一种感觉,我的弹出功能是错误的。但我不确定到底哪里错了。我已经多次检查我的逻辑哪里出错了,但它似乎完全正确(使用CLRS伪代码检查)

类优先级队列:
“”“基于数组的优先级队列实现。”“”
定义初始化(自):
“”“初始优先级队列为空。”“”
self.queue=[]
self.min_索引=无
def父级(自我,i):
返回整数(i/2)
def left(self,i):
返回2*i+1
定义权限(self,i):
返回2*i+2
def min_heapify(自身、堆大小、i):
#CLRS中写入的最小heapify
最小值=i
l=自左(i)
r=自右(i)
#打印([l、r、len(self.queue)、堆大小])
尝试:
如果l0和self.queue[self.parent(i)]>self.queue[i]:
self.queue[i],self.queue[self.parent(i)]=self.queue[self.parent(i)],self.queue[i]
i=自我父母(i)
定义(自我):
#队列中的元素数。
返回len(自队列)
def附加(自身,密钥):
“”“在优先级队列中插入一个元素。”“”
如果键为“无”:
raise VALUERROR('无法在队列中插入任何')
self.queue.append(键)
堆大小=len(self.queue)
self.heap\u reduce\u键(heap\u size-1,键)
def最小值(自身):
“”“队列中最小的元素。”“”
如果len(self.queue)==0:
一无所获
返回self.queue[0]
def pop(自我):
“”“删除队列中的最小元素。
返回:
已删除元素的值。
"""
如果len(self.queue)==0:
一无所获
self._find_min()
弹出的\u键=self.queue[self.min\u索引]
self.queue[0]=self.queue[len(self.queue)-1]
del self.queue[-1]
self.min_索引=无
self.min\u heapify(len(self.queue),0)
返回弹出键
定义查找最小值(自):
#计算队列中最小元素的索引。
#
#如果在队列为空时调用此方法,则该方法可能会崩溃。
如果self.min_索引不是无:
返回
min=self.queue[0]
self.min_索引=0

任何提示或输入都将受到高度赞赏

您的
父功能已经错误

堆的根元素存储在数组索引0中,子元素存储在1和2中。1的父级是0,这是正确的,但是2的父级也应该是0,而您的函数返回1

通常,堆的底层数组不使用索引0,而是根元素位于索引1处。通过这种方式,您可以像这样计算父项和子项:

parent(i): i // 2
left_child(i): 2 * i
right_child(i): 2 * i + 1

您的
父函数
已经错误

堆的根元素存储在数组索引0中,子元素存储在1和2中。1的父级是0,这是正确的,但是2的父级也应该是0,而您的函数返回1

通常,堆的底层数组不使用索引0,而是根元素位于索引1处。通过这种方式,您可以像这样计算父项和子项:

parent(i): i // 2
left_child(i): 2 * i
right_child(i): 2 * i + 1

主要问题是
父函数
错误。由于它应该与
left
right
方法相反,因此在将该值减半之前,应首先从
i
中减去1:

def parent(self, i):
    return int((i-1)/2)
其他需要注意的事项:

  • 您对成员
    self.min\u index
    的使用不是很好。它要么是0,要么是
    None
    ,而这个差异实际上并没有在代码中使用,因为它直接取决于堆是否为空。这也意味着您不需要方法
    \u find\u min
    ,(这本身很奇怪:您分配给
    min
    ,但从不使用该方法)。不管怎样,放下那个方法和你调用它的那一行。另外,删除将
    None
    分配给
    self.min_index
    的行,以及读取值的唯一其他位置,只需使用0即可

  • min\u heapify
    方法中,有两种方法可以防止索引错误:
    self[i]:
    raise VALUE ERROR(“新键大于当前键”)
    self[i]=键
    而i>0和self[self.parent(i)]>self[i]:
    self[i],self[self.parent(i)]=self[self.parent(i)],self[i]
    i=自我父母(i)
    def附加(自身,密钥):
    “”“在优先级队列中插入一个元素。”“”
    如果键为“无”:
    raise VALUERROR('无法在队列中插入任何')
    super().append(键)
    堆大小=len(自身)
    self.heap\u reduce\u键(heap\u size-1,键)
    def最小值(自身):
    “”“队列中最小的元素。”“”
    如果len(self)==0:
    一无所获
    返回自我[0]
    def pop(自我):
    “”“删除队列中的最小元素。
    返回:
    已删除元素的值。
    """
    如果len(self)==0:
    一无所获
    弹出的_键=自身[0]
    self[0]=self[-1]
    德尔赛尔夫[-1]
    self.min_heapify(0)
    返回弹出键
    
    主要问题是
    父函数
    错误。由于它应该与
    left
    right
    方法相反,因此在将该值减半之前,应首先从
    i
    中减去1:

    def parent(self, i):
        return int((i-1)/2)
    
    其他需要注意的事项:

    • 您对成员
      self.min\u index
      的使用不是很好。它要么是0,要么是
      None
      ,而这个差异实际上并没有在代码中使用,因为它直接取决于堆是否为空。这也意味着您不需要方法
      \u find\u min
      ,(这本身很奇怪:您分配给
      min
      ,但从不使用该方法)。不管怎样,放下那个方法和你调用它的那一行。另外,删除将
      None
      分配给
      self.min_index
      的行,以及读取值的唯一其他位置,只需使用0即可

    • min\u heapify
      方法中,有两种方法可以防止索引错误