问题:考虑一个具有l级的完整k-ary树,其节点在广度优先遍历中按其等级标记 . 按照深度优先遍历中遍历的顺序计算标签列表 .
例如,对于具有3个级别的二叉树,所需列表为:[0 1 3 7 8 4 9 10 2 5 11 12 6 13 14]
实现此目的的一种方法是实际构建树结构并遍历它两次;第一次遍历是广度优先,标记节点0,1,2,..当你去 . 第二次遍历是深度优先,报告标签0,1,3,7,..当你去 .
我对避免在内存中构建树的方法感兴趣 . 我意识到这种树的大小与输出的大小相当,但我希望解决方案允许“流”输出(即不需要完全存储在内存中) .
我也对伴侣问题感兴趣;从根据深度优先遍历标记的树开始,并生成广度优先遍历的标签 . 我想在某种意义上,这个问题的解决方案将是第一个问题的双重解决方案 .
3 回答
您实际上不需要构建树 . 您可以仅使用BFS标签而不是指向实际节点的指针来执行深度优先遍历 .
使用BFS位置标签表示k-ary树中的节点:
根是
0
任何节点的第一个子节点
n
是k*n + 1
节点
n
的正确兄弟,如果有的话,是n+1
在代码中它看起来像这样:
这实际上一直用于表示数组中的二进制堆 - 节点是BFS顺序中的数组元素,并且通过对索引执行这些操作来遍历树 .
您可以使用标准DFS和BFS算法,但不是从预构建的树结构获取特定节点的子节点,而是可以根据需要计算它们 .
对于高度为H的BFS编号的完整K-ary树,深度为D的节点N的第i个子节点为:
提供
i = 0
(第一个孩子)here时该公式的推导 .对于高度为H的DFS编号的完整K-ary树,深度为D的节点N的第i个子项由更加丑陋的公式给出:
以下是对此公式的粗略解释:
下面是一个Python实现(注意:
dfs
函数使用BFS公式,因为它正在从DFS转换为BFS,反之亦然_2977402_函数 . ):以上将打印:
这里有一些似乎可以解决问题的javascript .
它是深度优先搜索,用于在向下计算每个节点的BFS标签 .
它使用当前深度
dep
,当前行中的水平位置(pos
)和行中第一个节点的标签(rowstart
)计算节点的标签 .