【问题标题】:How to implement heap traversal in Python如何在 Python 中实现堆遍历
【发布时间】:2016-11-22 20:04:27
【问题描述】:

我刚刚在 python 中创建了一个堆类,并且仍在使用树遍历。当我调用inoder function 时,我收到错误消息None is not in the list。在我的三个遍历函数中,都需要leftright函数。我认为问题出在这两个函数上,但我不知道如何解决。

class myHeap:
    heapArray = []

    def __init_(self):
            self.heapArray = []

    def __str__(self):
            string = " ".join(str(x) for x in self.heapArray)
            return string

    def makenull(self):
            self.heapArray = []

    def insert(self, x):
            self.heapArray.append(x)
            self.upheap(self.heapArray.index(x))

    def parent(self, i):
            p = (i - 1) / 2
            p = int(p)
            if(p >= 0):
                    return self.heapArray[p]

            else:
                    return None

    def left(self, i):
            l = (i + 1) * 2 - 1
            l = int(l)
            if(l < len(self.heapArray)):
                    return self.heapArray[l]
            else:
                    return

    def right(self, i):
            r = (i + 1) * 2
            r = int(r)
            if(r < len(self.heapArray)):
                    return self.heapArray[r]
            else:
                    return None
    def swap(self, a, b):
            temp = self.heapArray[a]
            self.heapArray[a] = self.heapArray[b]
            self.heapArray[b] = temp

    def upheap(self, i):
            if(self.parent(i) and self.heapArray[i] < self.parent(i)):
                    p = (i - 1) / 2
                    p = int(p)
                    self.swap(i, p)
                    i = p
                    self.upheap(i)
            else:
                    return

    def downheap(self, i):
            if(self.left(i) and self.right(i)):
                    if(self.left(i) <= self.right(i)):
                            n = self.heapArray.index(self.left(i))
                            self.swap(i, n)
                            self.downheap(n)
                    else:
                            n = self.heapArray.index(self.right(i))
                            self.swap(i, n)
                            self.downheap(n)
            elif(self.left(i)):
                    n = self.heapArray.index(self.left(i))
                    self.swap(i, n)
                    self.downheap(n)
            elif(self.right(i)):
                    n = self.heapArray.index(self.right())
                    self.swap(i,n)
                    self.downheap(n)
            else:
                    return

    def inorder(self, i):
            if(self.heapArray[i] != None):
                    self.inorder(self.heapArray.index(self.left(i)))
                    print(self.heapArray[i], end=" ")
                    self.inorder(self.heapArray.index(self.right(i)))

    def preorder(self, i):
            if(self.heapArray[i] != None):
                    print(self.heapArray[i], end=" ")
                    self.preorder(self.heapArray.index(self.left(i)))
                    self.preorder(self.heapArray.index(self.right(i)))

    def postorder(self, i):
            if(self.heapArray[i]!= None):
                    self.postorder(self.heapArray.index(self.left(i)))
                    self.postorder(self.heapArray.index(self.right(i)))
                    print(self.heapArray[i], end=" ")

    def min(self):
            return self.heapArray[0]

    def deletemin(self):
            self.swap(0, len(self.heapArray) - 1)
            self.heapArray.pop
            self.downheap(0)

def main():
    heap = myHeap()
    heap.insert(0)
    heap.insert(15)
    heap.insert(7)
    heap.insert(8)
    heap.insert(1)
    heap.insert(2)
    heap.insert(22)
    print(heap)
    print(heap.heapArray[0])
    heap.inorder(0)
    heap.preorder(0)
    heap.postorder(0)

if __name__ == "__main__":
    main()

【问题讨论】:

  • 拥有计算 leftindex() 和 rightindex() 的函数可能更容易,并且在需要值时直接使用这些索引访问底层数组。您正在计算左子索引 O(1),所以只需返回它,而不是返回左子的值,然后在列表上执行 O(n) 搜索以找到您的左子索引已经知道了。

标签: python heap binary-tree tree-traversal


【解决方案1】:

当你跟随树到它的左孩子,并且没有左孩子,那么你应该完成那条路径。保证您最终会得到 None left child,这应该是您结束递归的基本情况。

相反,您查找左孩子的值(使用其索引),然后从该值反向计算您已经拥有的索引(希望没有重复)。由于最终会有 None 左孩子,当您尝试反向计算 None 的索引时,您会发现“self.heapArray”中没有 None 并得到确切的错误“None is not in list”

【讨论】:

    【解决方案2】:

    想象一下在叶节点上调用 inorder 会发生什么。它进入 if 语句的主体并尝试获取叶节点的左右子节点——但没有子节点——所以当 self.left(i) 评估为 None 并被输入到 index 方法时它会阻塞。您需要修改结束递归的方式,以检查该节点是否有左右子节点。

    【讨论】:

      猜你喜欢
      • 2019-05-13
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 2014-06-05
      • 2020-04-11
      • 1970-01-01
      • 2012-06-07
      • 2011-07-12
      相关资源
      最近更新 更多