高效的算法来创建一个你知道每个元素路径的树
Efficient algorithm to create a tree where you know each elements path
这可能是一个很容易回答的问题,但由于某种原因,我的大脑一片空白,一直无法想出有效的解决方案。
任务是这样的:我有一些元素,其中包含一个数组(它们的路径)和它们的名称。我想从这个列表中以格式创建一棵树(带符号的特定语法并不重要)
Elements:
( name: Element 1,
Elements:
( name: Element 1.1
)
Name: Element 2,
Elements:
( ... )
)
鉴于以下样式的项目,您对尽可能高效地解决此任务的算法有什么建议吗?
商品样式为:[ Great Grandfather, Grandfather, Father ], Element Name
.
并且路线的元素数量可以是任意数量。我能想到的唯一明显的解决方案是从每个父数组中的第一项开始,如果它们不存在则将它们添加到树中,然后移动到 Parents[1]
然后 Parents[2]
等... 有任何想法吗?
我看到至少有两种方法。比较简单的是O(n d ln b)
,d
是最大深度,b
是分支因子,即maximum/average个children每parent.您可能会假设这些常量(因此使用 O(n)
),但它们可能在功能上依赖于 n
.
另一个是 O(n)
时间,但可能会由于哈希函数错误和其他原因而降级为二次。
版本 1
- 每个节点保留其 children 的有序列表。
从根向下,找到下一个child,即
如果路径是 A.B.C
,找到 A
,然后递归到 A
并找到 B
。
最后插入 C
作为 B
的 child(如果 C
不存在)。
使用binarySearch()
查找插入点(或匹配元素)。
由于children的列表是排序的,所以个人搜索是O(ln(b))
,其中b
最大的是children。您最多需要深入 d
个级别,因此 O(d ln(b))
。整个过程需要重复 n
次。
版本 2
这会占用更多内存,实际上可能不会更快。
在构建树的同时,保留一个映射 path-to-node -> 节点.
每当你遇到一个节点输入
- 通过地图内的路径查找节点的 parent (
O(1)
)。
- 将 child 附加到 parent 并将新节点的完整路径存储在地图中。
如果你假设散列 table 像宣传的那样工作,你会得到 O(n)
(或者 O(n ln(n))
如果 children 已排序)但需要有足够的内存对于散列 table.
由于版本 2 似乎并没有那么好,我会坚持使用实施起来更简单的版本 1。
这可能是一个很容易回答的问题,但由于某种原因,我的大脑一片空白,一直无法想出有效的解决方案。
任务是这样的:我有一些元素,其中包含一个数组(它们的路径)和它们的名称。我想从这个列表中以格式创建一棵树(带符号的特定语法并不重要)
Elements:
( name: Element 1,
Elements:
( name: Element 1.1
)
Name: Element 2,
Elements:
( ... )
)
鉴于以下样式的项目,您对尽可能高效地解决此任务的算法有什么建议吗?
商品样式为:[ Great Grandfather, Grandfather, Father ], Element Name
.
并且路线的元素数量可以是任意数量。我能想到的唯一明显的解决方案是从每个父数组中的第一项开始,如果它们不存在则将它们添加到树中,然后移动到 Parents[1]
然后 Parents[2]
等... 有任何想法吗?
我看到至少有两种方法。比较简单的是O(n d ln b)
,d
是最大深度,b
是分支因子,即maximum/average个children每parent.您可能会假设这些常量(因此使用 O(n)
),但它们可能在功能上依赖于 n
.
另一个是 O(n)
时间,但可能会由于哈希函数错误和其他原因而降级为二次。
版本 1
- 每个节点保留其 children 的有序列表。
从根向下,找到下一个child,即 如果路径是
A.B.C
,找到A
,然后递归到A
并找到B
。 最后插入C
作为B
的 child(如果C
不存在)。使用
binarySearch()
查找插入点(或匹配元素)。
由于children的列表是排序的,所以个人搜索是O(ln(b))
,其中b
最大的是children。您最多需要深入 d
个级别,因此 O(d ln(b))
。整个过程需要重复 n
次。
版本 2
这会占用更多内存,实际上可能不会更快。
在构建树的同时,保留一个映射 path-to-node -> 节点.
每当你遇到一个节点输入
- 通过地图内的路径查找节点的 parent (
O(1)
)。 - 将 child 附加到 parent 并将新节点的完整路径存储在地图中。
如果你假设散列 table 像宣传的那样工作,你会得到 O(n)
(或者 O(n ln(n))
如果 children 已排序)但需要有足够的内存对于散列 table.
由于版本 2 似乎并没有那么好,我会坚持使用实施起来更简单的版本 1。