提问者:小点点

我的自定义heapify方法在python中无法正常工作


我正在学习数据结构,我的代码工作不正常。。我尝试了dubugging,但找不到任何东西(似乎heapifyinsert()什么也没做)

这是我的代码:

class Heap:
    def __init__(self,size):
        self.heap=[None]*(size+1)
        self.heapsize=0
        self.maxheapsize=size+1


    def levelordertransversal(self):
        if not self.heap:
            raise Exception('Heap doesn\'t exists')
        for x in range(1,self.heapsize+1):
            print(self.heap[x])

    def heapifyinsert(self,index,heaptype):
        heaptype=heaptype.title()
        parentindex=int(index/2)
        if parentindex<=1:
            return
        if heaptype=='Min':
            if self.heap[index]<self.heap[parentindex]:
                temp=self.heap[index]
                self.heap[index]=self.heap[parentindex]
                self.heap[parentindex]=temp
            self.heapifyinsert(parentindex,heaptype)
        elif heaptype=='Max':
            if self.heap[index]>self.heap[parentindex]:
                temp=self.heap[index]
                self.heap[index]=self.heap[parentindex]
                self.heap[parentindex]=temp
            self.heapifyinsert(parentindex,heaptype)

    def insertnode(self,nodevalue,heaptype):
        if self.heapsize+1==self.maxheapsize:
            raise Exception('Heap is full!!')
        self.heap[self.heapsize+1]=nodevalue
        self.heapsize+=1
        self.heapifyinsert(self.heapsize,heaptype)

h=Heap(5)
h.insertnode(4,'Max')
h.insertnode(5,'Max')
h.insertnode(2,'Max')
h.insertnode(1,'Max')
h.levelordertransversal()

当前输出:

4
5
2
1

预期产出:

5
4
2
1

因此,在上面的代码中,我试图实现堆,从索引位置1开始(为了简单起见),在heapify插入()方法中,我们将获取父索引,并根据堆类型检查父索引处的值是否更大或更小交换价值观

任何帮助或线索都将不胜感激。。谢谢


共1个答案

匿名用户

问题是递归停止得太快。1是堆中的有效索引,而0不是,这意味着您需要更改:

if parentindex<=1:

...到:

if parentindex< 1:

这将解决问题。

关于代码的其他一些注释:

>

  • 当子级和父级之间的比较正常时,递归可以停止。因此,如果块,则将self.heapifyinsert(父索引,heaptype)的调用移动到前面的块中。

    不应为insertnode定义heaptype参数,因为显然为insertnode的下一次调用提供不同的值是没有意义的:它应该始终为“Min”或始终为“Max”。因此,这应该是构造函数的参数,并作为堆的属性存储

    在Python中,您可以使用元组赋值轻松地交换值,而不需要temp变量

    int(index/2)将首先执行浮点除法并将其转换回整数。只使用整数除法更有意义:index//2

    如果不self.heap:是不必要的:因为heap属性是由构造函数初始化的,所以这种情况永远不会发生

    避免一些代码重复:交换和递归调用在堆类型上是相同的独立的,所以尝试重新排列代码,以便只编码一次。