【问题标题】:How to fix NoneType error in Python Binary Search Tree?如何修复 Python 二叉搜索树中的 NoneType 错误?
【发布时间】:2021-06-10 03:30:17
【问题描述】:

我正在创建一个基本的二叉搜索树程序,其中节点必须是字符串,但是,我不断收到此错误: 'builtins.AttributeError: 'NoneType' object has no attribute 'addNode'

我有点困惑,因为我认为您必须将子节点声明为 None。我的代码如下(请原谅凌乱和额外的打印语句):

class BinarySearchTree:
  #constructor with insertion value & left/right nodes as None
  def __init__(self, data):
    self.data = data
    self.left = None
    self.right = None
  
  #function to insert node
  def addNode(root, data):
    #when tree doesn't exist
    if root == None:
      return BinarySearchTree(data)
    else:
      #when node is already in tree
      if root.data == data:
        return root
      #smaller values go left
      elif data < root.data:
          root.left.addNode(data)
      #bigger values go right
      else:
          root.right.addNode(data)
    return root

  #function to find smallest node value (to help with deletion)  
  def smallestNode(root):
      node = root
      #loop goes to lowest left leaf
      while(node.left is not None):
          node = node.left
      return node

  #function to delete node
  def removeNode(root, data):
    if root == None:
      return root
    #when node to be deleted in smaller than root, go left
    if data < root.data:
      root.left = root.left.removeNode(data)
    #when node to be deleted in bigger than root, go right
    elif data > root.data:
        root.right = root.right.removeNode(data)
    ##when node to be deleted in the same as root...
    else:
        #when node has only 1 or 0 children
        if root.right == None:
            move = root.left
            root = None
            return move
        elif root.left == None:
            move = root.right
            root = None
            return move
        #when node has 2 children, copy then delete smallest node
        move = root.right.smallestNode()
        root.data = move.data
        root.right = root.right.removeNode(move.data)
    return root

  def findNode(root, data):
    #if current node is equal to data value then return the root
    if root.data == data or root == None:
      return root
    #if current node is greater than the data value then, search to the left
    elif data < root.data:
      return root.left.findNode(data)
    #if current node is less than the data value then, search to the right
    else:
      return root.right.findNode(data)

def createBST(keys):
  root = BinarySearchTree(keys[0])

  for i in range(1,len(keys)):
      root.addNode(keys[i])
  return root

print('Hi! Welcome to the Binary Search Tree Builder')
print('Here are your options below:')
print('1) Build new tree')
print('2) Add a node')
print('3) Find a node')
print('4) Delete a node')
choice = int(input('What would you like to do?: '))
if choice == 1:
  nodes = list(input("Enter the strings you would like to build your tree from (separate by a space): ").split())
  print(nodes)
  tree = createBST(nodes)
  print(tree)

我想知道这个错误究竟是从哪里来的,我该如何解决?另外,如果您发现我的代码中出现任何其他问题,请告诉我!

【问题讨论】:

  • 异常应该说明它发生在哪一行!您还可以使用 pdb module python -m pdb myprogram.py 在这样的程序中单步执行并设置断点
  • 执行root.left.addNode(data) 时会发生错误,因为您从未将任何内容放入root.left。解决这个问题不会让你的程序工作;整个设计有缺陷。见下文。

标签: python binary-search-tree nodes nonetype python-class


【解决方案1】:

您将“树节点”和“树”的概念混为一谈。你所拥有的是两者的混合物。请记住,所有成员函数的第一个参数应该是“self”。用“self”替换“root”可能会让你的问题更清楚。

因此,您可以创建一个 BinaryTree 类,该类具有一个名为 self.root 的单个成员,该成员拥有一个 BinaryTreeNode 对象,一旦您有了一个节点。节点将保存leftright 值,每个值都将具有NoneBinaryTreeNode 对象。节点类可能不需要太多代码——只需要self.leftself.right

BinaryTree 类将有一个 addNode 成员知道如何遍历树以找到正确的位置,但是当您找到位置时,您只需设置 self.left = BinaryTreeNode(...)。节点不知道树,因此节点不知道如何添加新节点。这是树本身的功能。

这会让你的前进道路更加清晰吗?

【讨论】:

  • 您创建 bintree 的一般准则并不能解决他的问题。
  • 他的错误是由于一个致命的缺陷设计。修复错误不会导致他找到解决方案。他需要重新开始。
猜你喜欢
  • 2022-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2010-12-23
  • 2019-04-15
相关资源
最近更新 更多