[英]n-ary tree insert algorithm in python
I'm trying to create sort of a nested round robin structure/tree where each child has N
items.我正在尝试创建一种嵌套循环结构/树,其中每个孩子都有
N
个项目。 I believe this is what a n-ary tree is (the closest thing I could find for what I'm after) but I was not able to find a good python implementation and am trying to see if I can get help doing this right我相信这就是一元树(我能找到的最接近我所追求的东西),但我找不到一个好的 python 实现,我想看看我是否能得到帮助做这件事
So for example a tree of N=3
, given an initial root {"key": 1, "children": []}
adding a new keys should result in this type of structure where each parent has max 3 children.因此,例如一棵
N=3
的树,给定一个初始根{"key": 1, "children": []}
添加一个新键应该会导致这种类型的结构,其中每个父级最多有 3 个子级。
Image of how it should look它应该看起来如何的图像
I'm definitely doing this in a very odd way and this is why I need guidance in either correcting my code or using a diff method entirely.我肯定是以一种非常奇怪的方式来做这件事,这就是为什么我需要指导来纠正我的代码或完全使用 diff 方法。
Here's my approach:这是我的方法:
For a given N the max number of items for a given height follow this equation (where the root node is h=1)对于给定的 N,给定高度的最大项目数遵循此等式(其中根节点为 h=1)
N = 3
max_items = lambda n, h: int(n**(h-1) + n**h + n**(h-2))
height_map = {i: max_items(N, i) for i in range(1, 10)} # just pre compute first 10 levels for testing
# to get which index of the parent height the new item will go to, use
# here, when inserting 8 [self.count=7 -> count+1=8], the idx should equal 1 implying it should go under "3"
idx = ((self.count+1) - height_map[height-1] - 1) // self.N**(height-2)
class Tree:
def __init__(self, N, tree):
self.N = N
self.count = 1
self.tree = tree
def add(self, item, tree=None, height=1):
max_items = lambda n, h: int(n**(h-1) + n**h + n**(h-2))
height_map = {i: max_items(self.N, i) for i in range(1, 10)}
tree = tree if tree else self.tree
if len(tree["children"]) >= self.N and height > 1:
if (self.count+1) <= height_map[height]:
idx = ((self.count+1) - height_map[height-1] - 1) // self.N**(height-2)
child = tree["children"][idx]
return self.add(item, child, height+1)
elif len(tree["children"]) >= self.N and height == 1:
return self.add(item, tree["children"][0], height+1)
else:
self.count += 1
tree["children"].append({"key": item, "children": []})
return tree
t = Tree(3, {"key": 1, "children": []})
for i in range (2, 8):
t.add(i)
print(t.tree)
This following code works great up to inserting 7 but there's some error in my logic that does not let you properly add 8 and manage the next depths.下面的代码在插入 7 时效果很好,但我的逻辑中有一些错误不能让您正确添加 8 并管理下一个深度。 I don't think I'm passing the root tree correctly as I get to the lower height but can't figure out how to fix this.
当我到达较低的高度时,我认为我没有正确传递根树,但不知道如何解决这个问题。
{'children': [{'children': [{'children': [], 'key': 5},
{'children': [], 'key': 6},
{'children': [], 'key': 7}],
'key': 2},
{'children': [], 'key': 3},
{'children': [], 'key': 4}],
'key': 1}
I'm not tied to the order the items are inserted either and only care about this structure but can't seem to make sense of it.我也不拘泥于插入项目的顺序,只关心这个结构,但似乎无法理解它。
Here is a simpler way of representing a 3-ary tree:这是表示三叉树的一种更简单的方法:
If you have the structure如果你有结构
a 0
/ | \ / | \
b c d 1 2 3
/|\ /|\ /|\ /|\ /|\ /|\
e f g h i j k l m 4 5 6 7 8 9 10 11 12
/| /|
n o 13 14
Represent it as a list:将其表示为列表:
[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
(The second list is just the indices of the nodes) (第二个列表只是节点的索引)
For a given node at index i
, it's children are at indices 3*i + 1
, 3*i + 2
and 3*i + 3
.对于索引
i
处的给定节点,它的子节点位于索引3*i + 1
、 3*i + 2
和3*i + 3
处。 For example, the children of node c
(index 2
) are h
, i
, and j
at indices 7
, 8
, 9
respectively.例如,节点
c
(索引2
)的子9
分别是8
7
处的h
、 i
和j
。
For a given node (except the root node) at index i
, the node's parent is at index (i - 1) / 3
.对于索引
i
处的给定节点(根节点除外),节点的父节点位于索引(i - 1) / 3
处。 For example, parent of node i
(index 8
) is 2
.例如,节点
i
的父节点(索引8
)是2
。
To add a new node, simply append to this list, and it will become the child of a node.要添加新节点,只需将 append 加入此列表,它将成为节点的子节点。
The tree will be complete (ie filled in at every possible level), except possibly for the last level which is filled-in from left to right.该树将是完整的(即在每个可能的级别都填充),除了可能从左到右填充的最后一个级别。
Note that this tree structure is quite similar to a heap but with 3 children instead of 2.请注意,此树结构与堆非常相似,但有 3 个孩子而不是 2 个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.