我正在尝试理解二叉树,但这样做让我对类实例如何交互产生了困惑,每个实例如何链接到另一个?
class Node(object):
def __init__(self, key):
self.key= key
self.L = None
self.R = None
class BinaryTree(object):
def __init__(self):
self.root = None
def get_root(self):
return self.root
def insert(self, key):
if self.get_root()==None:
self.root = Node(key)
else:
self._insert(key, self.root)
def _insert(self, key, node):
if key < node.key:
if node.L == None:
node.L = key
else:
self._insert(key, Node(node.L))
if key > node.key:
if node.R == None:
node.R = key
else:
self._insert(key, Node(node.R))
myTree= BinaryTree()
所以我想说我要插入10,我做myTree.insert(10)
这将实例化Node()
的新实例,这对我来说很清楚。
现在我要添加11,我希望它成为根节点的正确节点;即它将存储在根节点R
的属性Node()
中。
现在来到我不明白的部分。当我添加12时,它应该成为根节点右子的子节点。在我的代码中,这会创建Node()
的 new 实例,其中11应该是key
而12应该是R
。
所以我的问题是2倍: Node()
的最后一个实例会发生什么?如果不是如何访问它,它是否被删除?
或者是抽象的二叉树的结构,以便将每个连接在一起的Node()
视为图形
注意:这个实现很大程度上来源于此问题{djra的实现<{3}}
答案 0 :(得分:1)
制作L和R Node
而不是int
s。您可以通过更改_insert
功能的部分来完成此操作:
if node.L == None:
node.L = key
到此:
if node.L == None:
node.L = Node(key)
这一行还有一个问题:
self._insert(key, Node(node.L))
您现在正在执行此操作的方式,无法访问Node()
的最后一个引用,因为您的_insert
函数将其插入到没有父节点的匿名构造的节点下,因此不是你树的一部分。传入插入函数的节点不是树中任何其他节点的L
或R
,因此您实际上并未向树中添加任何内容。
既然我们已将L
和R
更改为Node
,您就可以将树的一部分节点传入插入功能:
self._insert(key, node.L)
现在你将节点的左边孩子传递给递归插入,这看起来就像你最初想做的那样。
对L
和R
插入案例进行代码更改后,您可以转到
Node()
的最后一个实例
10
\
11
\
12
示例树通过myTree.root.R.R
。您可以通过myTree.root.R.R.key
获取其密钥,等于12。
答案 1 :(得分:1)
你们大多数人的问题来自于没有完成该计划;在myTree.insert(11)
之后的当前代码中,您将树设置为R等于int
而不是另一个Node
。
如果未找到该值,则在该点创建新节点。否则将下一个节点传递给递归函数,以继续向下移动树。
def _insert(self, key, node):
if key < node.key:
if node.L == None:
node.L = Node(key)
else:
self._insert(key, node.L)
if key > node.key:
if node.R == None:
node.R = Node(key)
else:
self._insert(key, node.R)
P.S。这还没有结束你需要另一级别的逻辑测试,因为某些东西比当前Node.key
大但比下一个Node
小。