做测试的时候需要用随机生成的树, 并且能指定节点个数
算法思路
一, 对一个数字进行分割
对数字N, 将其分割为最多M个数字之和
想象有N个小球排成一列, 有N-1个空挡, 随机找M-1个空挡放入挡板, 在第一个小球前面, 和最后一个小球后面也放上挡板, 这样就有了M+1个挡板, 相邻两个挡板之间的距离就是分离出来的树, 如果有两个挡板在同一位置, 说明, 分离出来的数字中含有0
二, 前序递归建树
对于递归函数而言, buildTree(n) 表示 返回有n个节点树, 则n===1时 直接返回一个节点, n>1 时表示该节点含有子树, 需要进行拆分后, 依次创建子节点, 由于采用前序生成, 所以前序遍历的id序列即为增序序列
function splitInt(n, count) {
let list = [...Array(count - 1)]
.map(_ => Math.floor(Math.random() * n))
.sort((a, b) => a - b)
list.push(n)
list.unshift(0)
let res = []
for (let i = 1; i <= count; i++) {
res.push(list[i] - list[i - 1])
}
return res
}
class Node {
constructor(id, child = []) {
this.id = id
this.child = child
}
}
function getTree(count, maxChild = 16) {
let id = 0
// 创建有n个节点的树
function buildTree(n) {
if (n === 1) return new Node(id++)
let childCount = splitInt(n - 1, maxChild)
let root = new Node(id++)
for (let i of childCount) {
if (i < 1) continue
root.child.push(buildTree(i))
}
return root
}
return buildTree(count)
}
let root = getTree(100, 16)
// console.log(root)
function getNodeNum(root) {
let count = 0
function dfs(r) {
if (!r) return
count++
// console.log(r.id)
for (let i of r.child)
dfs(i)
}
dfs(root)
return count
}
console.log(getNodeNum(root))
来源:oschina
链接:https://my.oschina.net/ahaoboy/blog/3161260