减少一棵树的节点数,获取具有多个子节点的节点

Posted

技术标签:

【中文标题】减少一棵树的节点数,获取具有多个子节点的节点【英文标题】:Reducing the number of nodes of a tree, to obtain nodes with more than one child node 【发布时间】:2018-06-06 16:59:31 【问题描述】:

以下树:

已从以下矩阵中获得

> mat
7  23 47 41 31
7  23 53 41 31
7  23 53 41 37
7  29 47 41 31
7  29 47 41 37
7  29 53 41 31
7  29 53 41 37
11 29 53 41 31
11 29 53 41 37

将“mat”的每一列作为树的一个级别。如果'data'是存储矩阵'mat'的数据框

V1 V2 V3 V4 V5
7  23 47 41 31
7  23 53 41 31
7  23 53 41 37
7  29 47 41 31
7  29 47 41 37
7  29 53 41 31
7  29 53 41 37
11 29 53 41 31
11 29 53 41 37

生成上述树的代码如下

> data$pathString<-paste("0", data$V1,data$V2,data$V3,data$V4,data$V5,sep = "/")
> p_tree <- as.Node(data)
> export_graph(ToDiagrammeRGraph(p_tree), "tree.png")

我想对树进行如下修改: (1) 如果一个在“n”级的节点,用数字 x 标记,在“n+1”级只有一个子节点,用数字 y 标记,那么程序将这两个节点集中在一个节点中,该节点由乘积 x*y 的结果标记; 2) 如果'n+1'层的节点没有子节点,程序什么也不做,从另一个分支重新开始; 3) 如果级别'n+1'的节点有多个子节点,程序应用点(1)并从每个子节点重新开始。

例如,对于我们示例的树,代码应该:

用标记为 31*41*47=59737 的节点替换红圈中的节点 用标记为 53*41=2173 的节点替换橙色圈出的节点 用标记为 47*41=1927 的节点替换以绿色圈出的节点 用标记为 11*29*53*41=693187 的节点替换蓝色圈出的节点

【问题讨论】:

您正在处理的图表有多大。是数百万、数千还是数百个节点?图是静态的,您可以假设节点数据在每个树通道中都是稳定的吗?即数据在算法过程中是稳定的。 @Technophobe01,图是静态的,我的节点不超过100个 任何节点都可以有两个以上的孩子吗? @JuanAntonioRoldánDíaz,是的。 【参考方案1】:

试试这个:

  freq <- sapply(1:ncol(data), function(x) 
  df <- data[, 1:x, drop = FALSE]

  cc <- aggregate(df[, 1], as.list(df), FUN = length)
  merge(df, cc, by = colnames(df), sort = FALSE)[, "x"]
  )

data$pathString <- sapply(1:nrow(data), function(x) 
  g <- 1
  for(i in 2:ncol(freq)) g <- c(g, 
        if(freq[x, i] == freq[x, i - 1]) g[i - 1] else g[i - 1] + 1)

  paste0(c("0", tapply(unlist(data[x, , drop = TRUE]), g, prod)), collapse = "/")
)


p_tree <- as.Node(data)

plot(p_tree)

【讨论】:

以上是关于减少一棵树的节点数,获取具有多个子节点的节点的主要内容,如果未能解决你的问题,请参考以下文章

在 SML 中查找 2-3 树中的节点数

2021-07-11:给定一个棵完全二叉树,返回这棵树的节点个数,要求时间复杂度小于O(树的节点数)。

2021-07-11:给定一个棵完全二叉树,返回这棵树的节点个数,要求时间复杂度小于O(树的节点数)。

如何同时更新不同的节点子节点firebase android

算法题 119:完全二叉树的节点数(360笔试题)

一棵含有N个结点的K叉树,可能达到的最大深度和最小深度分别是多少?