【问题标题】:Binary tree count all child nodes in left and right side二叉树统计左右两边的所有子节点
【发布时间】:2020-12-17 06:35:04
【问题描述】:
                                     1
                                   /   \
                                 2       3
                                / \     / \
                               4   5   6   7
                             /      \       \
                           8          9      11
                          /                   \
                        10                      12
                       /  \
                     13    14

我有这样的二叉树。在这里,1 是父母,我想计算 1 左右两侧的所有孩子

我有以下 mysql 表结构

**id** **amount** **left** **right**
  1       3000       2        3
  2       3000       4        5
  3       750        6        7
  4       750        8      *null*
  5       3000    *null*      9
  6       750     *null*    *null*
  7       750     *null*      11
  8       750       10      *null*
  9       3000    *null*    *null*
 10       3000      13        14
 11       750     *null*      12
 12       3000    *null*    *null*  
 13       750     *null*    *null*
 14       3000    *null*    *null*
        

现在我想根据 ID 的计划数量计算所有左侧节点和右侧节点 虽然我有成千上万的数据。是否可以通过按计划数量区分所有节点来计算所有节点? 例如,如果 ID 2 在其左侧包含 5 个 ID(4、8、10、13、14)并且每个 ID 的计划金额不同,我可以计算 750 计划中有多少个 2 以下的 ID?使用php

fiddle

【问题讨论】:

  • 指定 MySQL 版本 - 这对您的任务至关重要。 Anycase - 在 MySQL 端执行此操作,而不是在 PHP 中。
  • MySQL 版本是 5.6 @Akina 请帮帮我!!谢谢
  • 您的版本不支持 CTE - 所以创建存储过程。
  • 我不知道...什么是存储过程??
  • 例如,如果 ID 2 的左侧包含 5 个 ID ( 4, 8, 10, 13, 14 ),并且每个 ID 的计划金额不同,我可以计算下有多少个 ID 2 在 750 计划中? 请显示开始 ID = 2 所需的结果。您需要一个输出的子节点总数吗?或 2 个单独的数字 - 对于分别为其父节点左侧或右侧的节点?

标签: php mysql recursion count binary-tree


【解决方案1】:
CREATE PROCEDURE count_nodes (IN id INT, IN amount INT)
BEGIN
CREATE TABLE temp (id INT PRIMARY KEY, amount INT, id_left INT, id_right INT, side INT);
INSERT INTO temp SELECT *, 0 FROM test WHERE test.id = id;
REPEAT
    INSERT IGNORE INTO temp
    SELECT test.*, CASE WHEN test.id = temp.id_left THEN 1 ELSE 2 END FROM test JOIN temp ON test.id IN (temp.id_left, temp.id_right);
UNTIL NOT ROW_COUNT() END REPEAT;
SELECT SUM(side=1) left_childs, SUM(side=2) right_childs FROM temp WHERE temp.amount = amount;
DROP TABLE temp;
END

fiddle

如果在id 的子树中没有以id 开头或提供amount 的行,则该过程将返回NULL。

该过程是循环安全的(不会导致错误源表数据的无限循环)。但是id_left = id_right 的错误数据是不安全的 - 这样的错误节点将被计为左侧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多