我刚刚学会了如何在C#中创建二进制搜索树。我决定尝试在Python 3.x中编写相同的代码。但是,当我使用我的Print方法时,出现了这个错误:
Traceback (most recent call last):
File "C:\Users\danie\Desktop\Python\BinarySearchTree\BinarySearchTree\BinarySearchTree.py", line 62, in <module>
b.BSTprint()
File "C:\Users\danie\Desktop\Python\BinarySearchTree\BinarySearchTree\BinarySearchTree.py", line 46, in BSTprint
BST.Print(current)
TypeError: Print() missing 1 required positional argument: 'cur'
问题是,我确实提出了所需的位置参数。我尝试自己修复它,发现如果我删除了 self 参数,它就可以了。但是,我一直认为你需要在所有类方法中都有 self 参数。我不知道出了什么问题。这是代码
import random
class BST:
#Node class
class Node:
data = None
left = None
right = None
def __init__(self, d):
self.data = d
first = None
#Add method
def Add(self, d):
#Checks if the Binary Search Tree is empty
if(BST.first == None):
BST.first = BST.Node(d)
#Debugging purposes
#print("Added: {}".format(d))
return;
else:
newNode = BST.Node(d)
cur = BST.first
while(cur != None):
if(cur.data < newNode.data):
if(cur.left == None):
cur.left = newNode
#print("Added: {}".format(newNode.data))
return
else:
cur = cur.left
elif(cur.data > newNode.data):
if(cur.right == None):
cur.right = newNode
#print("Added: {}".format(newNode.data))
return
else:
cur = cur.right
else:
print("Value already in BST")
return
def BSTprint(self):
current = BST.first
if(current == None):
return
BST.Print(current)
def Print(self, cur):
if(cur.left != None):
BST.Print(cur.left)
print(cur.data)
if(cur.right != None):
BST.Print(cur.right)
b = BST()
#Adds values into BST
for i in range(10):
x = random.randint(1,100)
b.Add(x)
b.BSTprint()
答案 0 :(得分:1)
你已经混淆了类变量和实例变量。
在Python中,方法的第一个参数是为调用对象保留的(除非在某些情况下它们不是,例如在classmethods或staticmethods中)。像这样修改Add方法:
class BST:
...
def Add(self, d):
if self.first is None:
self.first = BST.Node(d)
return
...
请注意BST.Node(d)
仍然是相同的,因为我指的是属于该类的东西:另一个类。
将BST.Print(current)
修改为self.Print(current)
。
将BST的根节点称为first
,而不是更喜欢root
,这种情况并不常见!
答案 1 :(得分:1)
我想强调的事情:
BST
是一个类
Print
是一个对象方法(绑定到对象而不是类),它需要传递对象引用(self
),这与其他语言Java / C ++不同。
你正在调用BST.Print
,这类似于在Java / C ++中调用静态方法,但它错了,因为Print
方法采用了对象参数
由于您正在调用一个对象绑定的方法(因为它需要self
参数),您需要使用对象调用它。
重点是:
如果您使用带有self参数的方法,那么应该使用对象调用它们。如果要从类中调用它们,则可以使用@staticmethod
并删除self参数并传递要处理的对象
请参阅: Difference between Class and Instance methods
希望这有帮助
答案 2 :(得分:0)
正如其他人所说,在self.BSTprint(node)
方法中,您需要将first = None
作为实例方法调用,例如first
,以便将实例正确传递给方法。但是您的代码还存在一些其他问题。
执行BST
创建BST
作为类属性,这意味着它将由所有first
个实例共享。这不是一个好主意:每个实例都应该有自己的根节点!当然,如果程序只创建一个__init__
实例,您就不会注意到该错误,但如果您决定要创建多个树,则会发生错误的事情。 ;)
相反,您应该创建Node
作为实例属性,通常的方法是使用Node
方法。
您的代码定义了BST类中的Add
类。这样做很好,但在Python中有点不寻常。将它作为一个单独的类更简单。再一次,您将is
属性定义为类属性。这实际上是可以的,因为你从不修改那些类属性:你的None
方法创建具有“阴影”类属性的相同名称的实例属性。但是,如果你摆脱了那些类属性并且只是从一开始就使用实例属性,它会使代码分析更简单。
以下是您的代码的修改版本。我做了一些修饰,以便代码符合Python PEP-0008样式指南。简单的变量,属性和方法名称应以小写字母开头。我也摆脱了多余的括号。并且建议在测试==
单例时使用!=
,与使用first
或root
值测试相比,它更有效(并且更好阅读)。
根据BerkÖzbalcı的评论,我将Node
更改为__repr__
。我给了random.seed
一个import random
random.seed(42)
class Node:
""" A binary tree node """
def __init__(self, d):
self.data = d
self.left = self.right = None
def __repr__(self):
return repr(self.data)
class BST:
""" Binary search tree """
def __init__(self):
self.root = None
def add(self, d):
# Check if the Binary Search Tree is empty
if self.root is None:
self.root = Node(d)
#Debugging purposes
print("Added: {} root".format(self.root))
return
else:
newNode = Node(d)
cur = self.root
while cur is not None:
if cur.data < newNode.data:
if cur.left is None:
cur.left = newNode
print("Added: {} left".format(newNode))
return
else:
cur = cur.left
elif cur.data > newNode.data:
if cur.right is None:
cur.right = newNode
print("Added: {} right".format(newNode))
return
else:
cur = cur.right
else:
print("Value already in BST:", d)
return
def bst_print(self):
current = self.root
if current is None:
return
self.show(current)
def show(self, cur=None):
if cur.left is not None:
self.show(cur.left)
print(cur)
if cur.right is not None:
self.show(cur.right)
b = BST()
# Add values into BST
for i in range(10):
x = random.randint(1, 100)
print(x)
b.add(x)
print('\nSorted')
b.bst_print()
方法,以便更轻松地打印节点数据。
我还添加了对82
Added: 82 root
15
Added: 15 right
4
Added: 4 right
95
Added: 95 left
36
Added: 36 left
32
Added: 32 right
29
Added: 29 right
18
Added: 18 right
95
Value already in BST: 95
14
Added: 14 left
Sorted
95
82
36
32
29
18
15
14
4
的调用,其中包含硬编码的种子值,以便程序在每次运行时生成相同的数字。这使得测试和调试变得更加容易。当数据不断变化时,很难弄清楚出了什么问题。
{{1}}
<强>输出强>
{{1}}