繁体   English   中英

在 r 中将节点向量的顺序从级别顺序更改为中缀顺序

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM