Python BST无法正常工作

时间:2016-08-15 19:34:26

标签: python binary-search-tree

我是Python的新手,因此问题是,这是我的BST的实现

class BST(object):
    def __init__(self):
        self.root = None
        self.size = 0

    def add(self, item):
        return self.addHelper(item, self.root)

    def addHelper(self, item, root):
        if root is None:
            root = Node(item)
            return root

        if item < root.data:
            root.left = self.addHelper(item, root.left)
        else:
            root.right = self.addHelper(item, root.right)

这是Node对象

class Node(object):
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

这是我对 str

的暗示
def __str__(self):
    self.levelByLevel(self.root)
    return "Complete"



 def levelByLevel(self, root):

        delim = Node(sys.maxsize)
        queue = deque()
        queue.append(root)
        queue.append(delim)
        while queue:
            temp = queue.popleft()
            if temp == delim and len(queue) > 0:
                queue.append(delim)
                print()
            else:
                print(temp.data, " ")
                if temp.left:
                    queue.append(temp.left)
                if temp.right:
                    queue.append(temp.right)

这是我的主叫客户,

def main():
    bst = BST()
    bst.root = bst.add(12)
    bst.root = bst.add(15)
    bst.root = bst.add(9)

    bst.levelByLevel(bst.root)


if __name__ == '__main__':
    main()

而不是按级别打印BST级别的预期输出,而是获得以下输出,

9  
9223372036854775807  

当我查看调试器时,似乎每次调用add方法时,它都以root为开始,然后以root身份返回最后一个数字。我不确定为什么会这样。 任何帮助赞赏。

3 个答案:

答案 0 :(得分:1)

如果root的{​​{1}}参数为addHelper,则将其设置为新创建的None对象并将其返回。如果不是,则修改参数但不返回任何内容,因此最终再次将Node设置为bst.root。请尝试使用上面的代码 - 它应该有助于您理解代码的作用。

None

所以你应该做两件事:

  1. bst = BST() bst.root = bst.add(12) try: print(bst.root.data) except AttributeError: print('root is None') # => 12 # `bst.addHelper(12, self.root)` returned `Node(12)`, # which `bst.add` returned too, so now `bst.root` # is `Node(12)` bst.root = bst.add(15) try: print(bst.root.data) except AttributeError: print('root is None') # => root is None # `bst.addHelper(15, self.root)` returned `None`, # which `bst.add` returned too, so now `bst.root` # is `None`. bst.root = bst.add(9) try: print(bst.root.data) except AttributeError: print('root is None') # => 9 # `bst.addHelper(9, self.root)` returned `Node(9)`, # which `bst.add` returned too, so now `bst.root` # is `Node(9)` 始终返回其最后一个参数 - 经过适当修改后 - 和
  2. 让您的addHelper函数负责将结果分配给add(不要让它留给类用户做)。
  3. 以下是代码:

    self.root

    请注意,为了清楚起见,我将def add(self, item): self.root = self.addHelper(item, self.root) self.size += 1 # Otherwise what good is `self.size`? def addHelper(self, item, node): if node is None: node = Node(item) elif item < node.data: node.left = self.addHelper(item, node.left) else: node.right = self.addHelper(item, node.right) return node 中的最后一个参数的名称更改为addHelper(已经存在名为node的内容:树的内容!)。

    您现在可以按如下方式编写root函数:

    main

    (这正是@AaronTaggart建议的 - 但您需要def main(): bst = BST() bst.add(12) bst.add(15) bst.add(9) bst.levelByLevel(bst.root) add中的修改。它的输出是:

    addHelper

    上面介绍了一个有效的二叉搜索树。几点说明:

    1. 我会进一步修改你的12 9 15 9223372036854775807 以避免打印最后一个值,以及不接受任何参数(当然除levelByLevel之外) - 它应该始终从树的根目录打印。
    2. self会引发错误。您可以通过更改bst.add(None)方法来防范它。一种可能性是

      add

      另一种选择(更快,因为如果它是def add(self, item): try: self.root = self.addHelper(item, self.root) self.size += 1 except TypeError: pass 则拒绝继续处理item

      None
    3. 从设计的角度来看,我希望从二叉搜索树中选择一个节点会给我下面的子树。它以某种方式(节点包含对下面所有其他节点的引用),但仍然是:def add(self, item): if item is not None: self.root = self.addHelper(item, self.root) self.size += 1 Node对象是不同的东西。您可能想要想出一种统一两者的方法(这是@ YairTwito答案中的要点)。

    4. 最后一件事:在Python中,convention for naming things是小写单词并用下划线分隔,而不是你正在使用的camelCasing - 所以BST代替add_helper。我会在开头添加一个下划线,表示它不适合公众使用 - 所以addHelper或简称_add_helper

答案 1 :(得分:0)

您使用BST对象基本上只能保留根Nodeadd函数不会对BST对象进行操作所以最好只有一个班级(BtsNode)并在那里实施add。试试这个,你会发现add函数会简单得多。 并且,通常,当成员函数不使用self时,它不应该是成员函数(如addHelper),即它不应该self BtsNode 1}}作为参数(如果您希望我能告诉您如何编写BST类)。

我尝试编写一个使用您如何实现class BstNode: def __init__(self): self.left = None self.right = None self.data = None def add(self,item): if not self.data: self.data = item elif item >= self.data: if not self.right: self.right = BstNode() self.right.add(item) else: if not self.left: self.left = BstNode() self.left.add(item) 的想法的课程。

BST

这样您可以通过以下方式创建bst = BstNode() bst.add(13) bst.add(10) bst.add(20)

add

不同之处在于,现在add函数实际上对对象进行操作,而无需用户做任何事情。该函数自行更改对象的状态。

一般来说,一个功能应该只做它预期要做的事情。 bst.root = bst.add()函数应该将一个项添加到树中,因此它不应该返回根。您每次必须写public interface IAppSettings { string this[string key] { get; } } public class AppSettings : IAppSettings { public string this[string key] => ConfigurationManager.AppSettings[key]; } 的事实应该表明您的设计存在一些错误。

答案 2 :(得分:-1)

您的add方法可能不应返回值。而且你肯定不应该将树的根分配给add方法返回的内容。

尝试将主要代码更改为以下内容:

def main():
    bst = BST()
    bst.add(12)
    bst.add(15)
    bst.add(9)

    bst.levelByLevel(bst.root)


if __name__ == '__main__':
    main()