【问题标题】:Getting all nodes at a level in full binary tree, array format以全二叉树、数组格式获取所有节点
【发布时间】:2017-07-24 23:35:52
【问题描述】:

我需要从左子树或右子树中获取完整二叉树中某个级别的所有节点。我目前从数据库中检索二叉树作为数组,例如: [1,2,3,4,5,6,7] 代表这样的一棵树:

                                     1
                                    / \
                                   /   \
                                  2     3
                                 / \   / \
                                /   \ /   \
                               4    5 6    7

所以我需要做的基本上是获取树的一个级别并将其作为数组返回。类似于level(3,"left") -> [4,5]level(2, "right") -> [3]。我正在考虑创建一个 BinaryTree 对象以递归方式执行它,但我想不出一种方法来跟踪调用中的级别,而不必像我想保留的那样用级别或类似的东西标记每个节点数据库尽可能干净。有什么想法吗?

编辑:我真的需要左子树或右子树的所有节点,而不是整个树。我正在展示一场锦标赛,所以我需要将它分成两半。如果我不必拆分它,我可能会这样做:

function level($array, $level_num) {
    return array_slice($array, pow(2, $level_num)-1, pow(2, $level_num));
}

我真的不知道如何扩展它以仅获取左子树或右子树的级别数组。

【问题讨论】:

  • 这是一个非常酷的问题。试一试并显示您失败的代码。另请注意,您渲染的图像与示例数组不匹配。数组有 4 没有 8。图像没有 4 但有 8。
  • @BeetleJuice 抱歉,没注意到。刚刚更新了。
  • 好的,我写了一个解决方案。在您的 OP 中,level(3) 仍然包含 8,即使它不在树中。
  • @mickmackusa 是的,我的错,这是另一个错字。

标签: php arrays binary-tree


【解决方案1】:
// Adjust depth as needed
$depth = 3;

// using bit arithmetic. '<< 3' means multiply by 2 three times.
$start = 1 << $depth-1; // 1 * (2 * 2) because depth is 3
$end = (1 << $depth) -1; // 1 * (2 * 2 * 2) - 1

// if depth=3, this is [4,5,6,7]
$fullLevel = range($start, $end);

print_r($fullLevel);

if($depth > 1):
    $leftBranch = array_slice($fullLevel,0,count($fullLevel)/2);
    $rightBranch = array_slice($fullLevel,count($fullLevel) / 2);

    print_r($leftBranch); // [4,5]
    print_r($rightBranch); // [6, 7]
endif;

【讨论】:

  • 我也意识到获取左侧或右侧部分只是将其分成两半。使用&lt;&lt; 而不是pow() 有什么好处,还是我缺少一些区别?
  • @ashraj98 pow() 会远离你...这是demo
【解决方案2】:

我赞成 BeetleJuice 对使用“左移”按位运算符 &lt;&lt; 的回答——它是完成这项任务的完美构建块。

这是我可以尝试编码的最干净的:

代码:(Demo)

function getForkinValues($array,$level,$side='left'){ // left side fork is default
    if($level==1) return current($array);
    $length=$level>2?1<<($level-2):1;  // number of elements to return
    $index=(1<<$level-1)-1;            // first index to return
    if($side=='right') $index+=$length;  // shift to correct index for 'right'
    if(!isset($array[$index+$length-1])) return 'Error: Insufficient Array Length';
    return array_slice($array,$index,$length);

}
$array=['A','B','C','D','E','F','G'];
var_export(getForkinValues($array,3,'right'));

【讨论】:

  • @ashraj98 我没有引用任何索引。此功能(如 BeetleJuice 的)不会打扰“生长完整的树”。它确定树的指定“级别”中的整数,并在指定的分叉中返回一个值数组。构建一棵完整的树(多维数组)只是为了提取它的一小部分——效率低下/浪费。最佳做法是只构建您需要的东西。
  • 是的,我看了一会儿后才意识到这一点。假设树节点不是[1,2,3,4,5,...]?我仅以 OP 中的树为例。在实际使用中,节点值是 Laravel 中模型的 ID,因此不会像示例那样。
猜你喜欢
  • 2018-11-25
  • 2018-07-10
  • 2021-04-28
  • 2016-04-01
  • 1970-01-01
  • 2013-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多