Python 最小堆插入函数不使用';我不能正常工作

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

有人能帮我完成插入功能吗?我不知道为什么它不能正确插入数据

在测试文件中,预期的数组是:[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_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