Algorithm 实现优先级队列算法
这是我的PriorityQueue算法的实现。我有一种感觉,我的弹出功能是错误的。但我不确定到底哪里错了。我已经多次检查我的逻辑哪里出错了,但它似乎完全正确(使用CLRS伪代码检查)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
类优先级队列:
“”“基于数组的优先级队列实现。”“”
定义初始化(自):
“”“初始优先级队列为空。”“”
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
方法中,有两种方法可以防止索引错误