[英]Change order of vector of nodes from level order to infix order in r
我有一个从二元回归树中获取的节点向量。 这些是按级别顺序排列的,例如1,2,4,5,10,11
。 我想将它们按这样的中缀顺序放置: 4,2,10,5,11,1
。 感谢 Alistaire 我有一个使用递归的解决方案。 但正如他们指出的那样,“必须有更好的方法”。 我希望有人可以用非递归方法帮助我。 对于任何合理长度的向量,递归版本都非常慢。 我也尝试过使用 igraph 和 data.tree 创建一个二叉树,但我似乎无法从这些中获得我想要的顺序。
是的,可以在没有递归的情况下执行此操作,因为您正在处理二叉树,它具有固定结构,如以下深度为 5 的树:
假设我们有一个节点向量:
nodes <- c(1, 2, 4, 5, 10, 11)
首先,我们只需要一个深度合适的二叉树来容纳你最大的节点。 我们可以通过以下方式获得所需的深度:
depth <- ceiling(log(max(nodes), 2))
还有一个数据框,它给出了一个足够大的二叉树的节点号、深度和“左”,如下所示:
df <- data.frame(node = seq(2^(depth) - 1),
depth = rep(seq(depth), times = 2^(seq(depth) - 1)),
leftness = unlist(sapply(2^seq(depth) - 1,
function(x) (seq(x)[seq(x) %% 2 ==1])/(x + 1))))
但是,我们只需要与您的节点匹配的这棵树的子集:
df <- df[match(nodes, df$node),]
df
#> node depth leftness
#> 1 1 1 0.5000
#> 2 2 2 0.2500
#> 4 4 3 0.1250
#> 5 5 3 0.3750
#> 10 10 4 0.3125
#> 11 11 4 0.4375
我们可以根据左度对节点进行排序:
df$node[order(df$leftness)]
#> [1] 4 2 10 5 11 1
这是您的预期结果。
为了概括这一点,只需将上述步骤放在一个 function 中:
sort_left <- function(nodes) {
depth <- ceiling(log(max(nodes), 2))
df <- data.frame(node = seq(2^(depth) - 1),
depth = rep(seq(depth), times = 2^(seq(depth) - 1)),
leftness = unlist(sapply(2^seq(depth) - 1,
function(x) (seq(x)[seq(x) %% 2 ==1])/(x + 1))))
df <- df[match(nodes, df$node),]
df$node[order(df$leftness)]
}
所以我们可以这样做:
sort_left( c(1, 2, 4, 5, 10, 11))
#> [1] 4 2 10 5 11 1
或者,以您原始问题中的示例为例,
sort_left(c(1,2,4,5,10,11,20,21))
#> [1] 4 2 20 10 21 5 11 1
这是期望的结果。 一切都没有递归。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.