You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高效生成含N个叶节点、深度为D的随机非对称二叉树

高效生成指定叶节点数且深度受限的随机二叉树

核心思路

放弃“随机生成后筛选”的低效方式,直接基于动态规划+概率抽样构造符合要求的树:

  1. 按叶节点总数N,递归分配左右子树的叶节点数量,确保每棵子树的叶节点数≥1(避免退化的对称结构);
  2. 递归构造时严格控制剩余深度,保证最终树的深度不超过D;
  3. 从所有合法的叶节点分配组合中均匀抽样,确保生成的树分布无偏。

前置合法性校验

生成前先确认输入参数是否合法:

  • 若要生成非对称树,需满足N≥2;
  • 深度为D的二叉树最多容纳2^(D-1)个叶节点(满二叉树情况),若N超过该值则无法生成,直接抛出异常。

算法步骤

  1. 递归构造逻辑:
    • 若当前节点剩余允许深度为1,说明该节点必须是叶节点,直接返回;
    • 若剩余深度>1且需要生成k个叶节点(k≥2):
      • 枚举所有合法的左子树叶节点数l:1≤l≤k-1,且l和k-l都不超过剩余深度-1对应的最大叶节点数(即2^(剩余深度-2));
      • 从合法的(l, k-l)组合中随机选一组;
      • 递归构造左右子树,分别对应l和k-l个叶节点,剩余深度减1。
  2. 打破对称优化:
    • 当选中的l和k-l相等时,50%概率交换左右子树的构造顺序,避免生成完全对称的树结构。

代码示例(Python)

import random

class TreeNode:
    def __init__(self, val=None):
        self.val = val
        self.left = None
        self.right = None

def is_valid(N, D):
    # 校验参数合法性:非对称要求N≥2,且N不超过深度D对应的最大叶节点数
    if N < 2:
        return False
    max_possible_leaves = 2 ** (D - 1)
    return N <= max_possible_leaves

def generate_random_tree(N, D):
    if not is_valid(N, D):
        raise ValueError("N must be ≥2 and ≤ 2^(D-1)")
    
    def _build(required_leaves, remaining_depth):
        # 剩余深度为1时,当前节点必须是叶节点
        if remaining_depth == 1:
            return TreeNode(random.randint(1, 100))  # 随机生成节点值,可自定义
        
        # 枚举所有合法的左子树叶节点数
        max_sub_leaves = 2 ** (remaining_depth - 2)
        valid_left_counts = []
        for l in range(1, required_leaves):
            right_count = required_leaves - l
            if l <= max_sub_leaves and right_count <= max_sub_leaves:
                valid_left_counts.append(l)
        
        # 随机选择左子树的叶节点数
        left_count = random.choice(valid_left_counts)
        right_count = required_leaves - left_count
        
        # 构造当前节点及子树
        node = TreeNode(random.randint(1, 100))
        node.left = _build(left_count, remaining_depth - 1)
        node.right = _build(right_count, remaining_depth - 1)
        
        # 50%概率交换左右子树,打破对称
        if left_count == right_count and random.random() < 0.5:
            node.left, node.right = node.right, node.left
        
        return node
    
    return _build(N, D)

# 测试:生成10个叶节点、深度不超过4的随机二叉树
tree = generate_random_tree(10, 4)

效率优化建议

  • 预计算所有(required_leaves, remaining_depth)对应的合法左子树数量列表,避免递归时重复枚举;
  • 若需批量生成树,可缓存合法组合的抽样结果,进一步提升速度。

内容的提问来源于stack exchange,提问作者user12953893

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:20:03