Python 最小堆插入函数不使用';我不能正常工作
有人能帮我完成插入功能吗?我不知道为什么它不能正确插入数据 在测试文件中,预期的数组是:[None,-12,-11,-6,-9,-3,-5,-2,-1,-4]Python 最小堆插入函数不使用';我不能正常工作,python,heap,min-heap,Python,Heap,Min Heap,有人能帮我完成插入功能吗?我不知道为什么它不能正确插入数据 在测试文件中,预期的数组是:[None,-12,-11,-6,-9,-3,-5,-2,-1,-4] from functools import total_ordering import math class MinHeap: def __init__(self): self.arr_heap = [None] def __str__(self): return str(self.arr
from functools import total_ordering
import math
class MinHeap:
def __init__(self):
self.arr_heap = [None]
def __str__(self):
return str(self.arr_heap[1:])
def __repr__(self):
return str(self)
def get_left_pos(self, i:int) ->int:
return 2*i
def get_right_pos(self, i:int) ->int:
return 2*i+1
def get_parent_pos(self, i) ->int:
return math.floor(i/2)
def swap(self, pos_1, pos_2):
aux = self.arr_heap[pos_1]
self.arr_heap[pos_1] = self.arr_heap[pos_2]
self.arr_heap[pos_2] = aux
def is_a_leaf(self, posicao):
return posicao >= len(self.arr_heap)//2 and posicao <= len(self.arr_heap)
def heapify(self, pos_raiz_sub_arvore:int):
parent_pos = pos_raiz_sub_arvore
left_child_pos = self.get_left_pos(parent_pos)
right_child_pos = self.get_right_pos(parent_pos)
if not self.is_a_leaf(parent_pos):
if (self.arr_heap[parent_pos] > self.arr_heap[left_child_pos] or self.arr_heap[parent_pos] > self.arr_heap[right_child_pos]):
if self.arr_heap[left_child_pos] < self.arr_heap[right_child_pos]:
self.swap(parent_pos, left_child_pos)
self.heapify(left_child_pos)
else:
self.swap(parent_pos, right_child_pos)
self.heapify(right_child_pos)
def insert(self, element):
self.arr_heap.append(element)
current = self.arr_heap.index(element)
while self.arr_heap[current] < self.arr_heap[self.get_parent_pos(current)-1]:
self.swap(current, self.get_parent_pos(current))
current = self.get_parent_pos(current)
def remove(self):
element = self.arr_heap[1]
element_pos = len(self.arr_heap)-1
self.arr_heap[1] = self.arr_heap[element_pos]
self.arr_heap.pop(element_pos)
self.heapify(1)
return element
def __str__(self):
return str(self.arr_heap)
def __repr__(self):
return str(self)
但是函数返回:[None,-12,-9,-6,-11,-3,-5,-2,-1,-4]
from functools import total_ordering
import math
class MinHeap:
def __init__(self):
self.arr_heap = [None]
def __str__(self):
return str(self.arr_heap[1:])
def __repr__(self):
return str(self)
def get_left_pos(self, i:int) ->int:
return 2*i
def get_right_pos(self, i:int) ->int:
return 2*i+1
def get_parent_pos(self, i) ->int:
return math.floor(i/2)
def swap(self, pos_1, pos_2):
aux = self.arr_heap[pos_1]
self.arr_heap[pos_1] = self.arr_heap[pos_2]
self.arr_heap[pos_2] = aux
def is_a_leaf(self, posicao):
return posicao >= len(self.arr_heap)//2 and posicao <= len(self.arr_heap)
def heapify(self, pos_raiz_sub_arvore:int):
parent_pos = pos_raiz_sub_arvore
left_child_pos = self.get_left_pos(parent_pos)
right_child_pos = self.get_right_pos(parent_pos)
if not self.is_a_leaf(parent_pos):
if (self.arr_heap[parent_pos] > self.arr_heap[left_child_pos] or self.arr_heap[parent_pos] > self.arr_heap[right_child_pos]):
if self.arr_heap[left_child_pos] < self.arr_heap[right_child_pos]:
self.swap(parent_pos, left_child_pos)
self.heapify(left_child_pos)
else:
self.swap(parent_pos, right_child_pos)
self.heapify(right_child_pos)
def insert(self, element):
self.arr_heap.append(element)
current = self.arr_heap.index(element)
while self.arr_heap[current] < self.arr_heap[self.get_parent_pos(current)-1]:
self.swap(current, self.get_parent_pos(current))
current = self.get_parent_pos(current)
def remove(self):
element = self.arr_heap[1]
element_pos = len(self.arr_heap)-1
self.arr_heap[1] = self.arr_heap[element_pos]
self.arr_heap.pop(element_pos)
self.heapify(1)
return element
def __str__(self):
return str(self.arr_heap)
def __repr__(self):
return str(self)
所有其他测试都很好。我学习了MinHeaps,因此我可以用您的代码解决问题(是的……我没有生命;)。有两个问题,它们在同一条线上。该行是
insert
方法中的这一行:
while self.arr_heap[current] < self.arr_heap[self.get_parent_pos(current)-1]:
第四个测试失败的原因是新元素到达树的顶部,并且您的算法继续运行。由于元素现在没有父元素,因此代码在试图获取父元素的值时崩溃。答案是识别新元素何时到达树的顶部,然后停止。为此,请将该行修改为:
while current > 0 and self.arr_heap[current] < self.arr_heap[self.get_parent_pos(current)]:
可以更清晰地写为:
def get_parent_pos(self, i) ->int:
return i // 2
/
生成浮点结果,而“//”通过向下舍入生成整数结果。请记住这一点,因为您经常需要进行整数除法,“//”是一种更简洁、更容易的方法。您的测试代码不完整。它是一个实例方法,但没有封装在类定义中。我假设您正在使用某个测试框架来运行该代码。如果是这样,您应该定义运行测试所使用的内容,以便其他人可以尝试复制您的问题。我本来打算这么做的,但我不能,因为我没有所有的部分来这么做。(更新:我想我是通过unittest
模块弄明白的。这就是我做这件事的部分原因。我从中学到:))非常感谢你的回复,Crypto傻瓜。我刚刚更新了测试文件:)我在调试器中看到测试失败。在insert
中,它执行一次交换,然后如果测试第二次失败,则执行,然后该方法返回。我很久没有上过基本的算法课了。我不知道你的逻辑应该是什么…这是什么类型的。你在调试器下运行这个程序只是为了观察它在做什么。这类事情正是您想要一个好的可视化调试器的目的。只需进入insert
,并在执行时跳过每一行即可。评估一些相关的表达。如果你明白会发生什么,你就能明白。非常感谢你,傻瓜!
def get_parent_pos(self, i) ->int:
return math.floor(i/2)
def get_parent_pos(self, i) ->int:
return i // 2