英文:
Inserting a node in a complete binary tree with python
问题
递归调用该函数总是在树的左侧添加新节点,那么我该如何使其递归检查右侧呢?
要让递归函数检查树的右侧,你可以稍作修改。在函数的最后,当递归添加节点到左子树时,你可以添加一些条件来判断是否需要递归添加到右子树。以下是修改后的代码片段:
def append(self, data, root="_"):
if self.__root.value is None:
self.__root = TreeNode(data)
self.__len += 1
return
root = self.__root if root == "_" else root
if not root:
return False
if root.left is None and root.right is None:
root.left = TreeNode(data)
self.__len += 1
return True
elif root.left is not None and root.right is None:
root.right = TreeNode(data)
self.__len += 1
return True
elif root.left is not None and root.right is not None:
if self.append(data, root.left):
return
else:
self.append(data, root.right)
return
elif root.left is not None and root.right is not None:
if self.append(data, root.left):
return
else:
self.append(data, root.right)
return
在上述代码中,当左子树不为空且右子树不为空时,会递归地先尝试添加到左子树,如果添加失败,则会再次尝试添加到右子树。这样可以使递归函数检查右侧并添加节点到右子树。
英文:
How to insert a node in a complete binary tree without using queue DS? I tried the following code:
class TreeNode:
def __init__(self, value=None) -> None:
self.left = None
self.value = value
self.right = None
class Tree:
def __init__(self, root=None) -> None:
self.__root = root if not root else TreeNode(root)
self.__len = 1 if root else 0
def append(self, data, root="_"):
if self.__root.value is None:
self.__root = TreeNode(data)
self.__len += 1
return
root = self.__root if root == "_" else root
if not root:
return False
if root.left is None and root.right is None:
root.left = TreeNode(data)
self.__len += 1
return True
elif root.left is not None and root.right is None:
root.right = TreeNode(data)
self.__len += 1
return True
elif root.left is not None and root.right is not None:
if self.append(data, root.left):
return
else:
self.append(data, root.right)
return
the recursive call of that function always add the new node on the left side of the tree, so what should I do to make it recursively checks the right side too?
答案1
得分: 0
以下是您要翻译的代码部分:
class Tree:
def __init__(self) -> None:
self.__root = None
self.__len = 0
def append(self, data):
self.__len += 1
if self.__len == 1: # First node
self.__root = TreeNode(data)
return
node = self.__root
# Iterate all the bits except the leftmost 1 and the final bit
for bit in bin(self.__len)[3:-1]:
node = [node.left, node.right][int(bit)] # Choose side
if self.__len & 1: # Use final bit to determine where child goes:
node.right = TreeNode(data)
else:
node.left = TreeNode(data)
请注意,我已经忽略了代码中的注释和HTML转义字符。
英文:
First of all, the first line in your append
code seems to give a special meaning to the value in the root node. When it is None
it is not considered a real node, but to represent an empty tree. This is not a good approach. An empty tree is represented by a __root
that is None
-- nothing else. I would also suggest to remove the optional data argument from the constructor. Either the constructor should allow an arbitrary number of values or none at all. To allow one is odd and strengthens the idea that a tree could have a special None
in its root node.
To the core of your question. There is nice attribute to complete binary trees. The paths from the root to a leaf can be represented by a bit pattern, where a 0 means "go left" and a 1 means "go right". And the path to the "slot" where a new node should be injected has a relationship with the size of the tree once that node has been added:
new size | binary representation | path to new node |
---|---|---|
1 | 1 | [] |
2 | 10 | [left] |
3 | 11 | [right] |
4 | 100 | [left,left] |
5 | 101 | [left,right] |
In general the path to the new node is defined by the bits in the binary representation of the new tree size, ignoring the leftmost 1.
This leads to the following code:
class Tree:
def __init__(self) -> None:
self.__root = None
self.__len = 0
def append(self, data):
self.__len += 1
if self.__len == 1: # First node
self.__root = TreeNode(data)
return
node = self.__root
# Iterate all the bits except the leftmost 1 and the final bit
for bit in bin(self.__len)[3:-1]:
node = [node.left, node.right][int(bit)] # Choose side
if self.__len & 1: # Use final bit to determine where child goes:
node.right = TreeNode(data)
else:
node.left = TreeNode(data)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论