简体   繁体   English

如何从树中的任何父节点获取所有叶节点

[英]How to get all leaf nodes from any parent node in a tree

I am developing an app in android using Sqlite, I have a tree structure which I represent in the db like so : 我正在使用Sqlite在android中开发一个应用程序,我有一个树结构,我在数据库中表示如下:

        +------+------+-------+------+
        |comp_id nodeId parent| text |
        |------|------|-------|------|
        |  146 |  1   |  -1   | Top  |
        |      |      |       |      |
        | 146  |  2   |  1    | Ch1  |
        |      |      |       |      |
        | 146  |  3   |  2    | Leaf |
        |      |      |       |      |
        |  ... |      |       |      |
        | 152  |  1   |  -1   | Top  |
        +------+------+-------+------+

I am having difficulty coding an algorithm in a self contained method like below to return me all the leafs under any node. 我在像下面这样的自包含方法编码算法时遇到困难,无法在任何节点下返回所有叶子。

Node
{
   public Node[] getAllLeafs()
   {
      // traverse all the way down the tree
      // and get only leafs
   }
}

If there is a way to accomplish this more easily by modifying my table structure and/or using SQL please mention that as I am able to do so. 如果有一种方法可以通过修改我的表结构和/或使用SQL来更容易地实现这一点,请提及我能够这样做。

Select all rows whose node_id s are not parents of some other rows, ie they are leaves. 选择node_id不是某些其他行的父项的所有行,即它们是叶子。

select *
from   tree_table
where  node_id not in (
   select distinct parent from tree_table
);

You can make a recursive method, that would return an array of all the leafs from its children, if a node has children, or the Node itself, if it doesn't have children, therefore is a leaf itself. 您可以创建一个递归方法,如果一个节点有子节点,则返回其子节点中所有叶子的数组,如果它没有子Node ,则返回Node本身,因此它本身就是一个叶子。

public Node[] getAllLeafs() {

    ArrayList<Node> allLeafs = new ArrayList<Node>();

    if (getAllChildren().size() == 0) {
        allLeafs.add(this);
        return (Node[]) allLeafs.toArray();
    } else {
        for (Node child : this.getAllChildren()) {
            allLeafs.addAll(child.getAllLeafs());
        }
    }
}

This way you can keep the logic within one method and don't have to redundantly traverse unimportant nodes. 这样,您可以将逻辑保留在一个方法中,而不必冗余地遍历不重要的节点。 The implementation of the structural methods is up to you. 结构方法的实施取决于您。

I think this logic would work: 我认为这种逻辑可行:

select node_id
from tree_table where node_id not in 
(select a.node_id 
from tree_table as a, tree_table as b
where a.node_id = b.parent); 

The inner query finds out those nodes which are also parents in the same table. 内部查询找出那些也是同一个表中的父节点的节点。 The outer query finds out the nodes which are not parents of any node and hence must be leaf nodes. 外部查询找出不是任何节点的父节点的节点,因此必须是叶节点。 Hope this helps! 希望这可以帮助!

Well, what is the reason to fetch all nodes under instead of all direct nodes? 那么,获取所有节点而不是所有直接节点的原因是什么? Second option is obviously simple. 第二种选择显然很简单。

I don't think that there is a reasonable solution, maybe graph databases. 我不认为有一个合理的解决方案,也许是图形数据库。 The point is that you can either: 关键是你可以:

  1. To have all parent ids (direct and non-direct) persisted along with every node. 使所有父ID(直接和非直接)与每个节点一起保持。 You could design new table having foreign keys for that. 您可以设计具有外键的新表。 But this solution seems like heavyweight. 但这个解决方案似乎是重量级的。 Speaking of which such table should grow exponentially. 说到这样的表应该呈指数增长。

  2. To fetch the whole tree together . 一起取整棵树。 This is the approach we are using within our app after four years of database research. 这是我们在经过四年的数据库研究后在我们的应用程序中使用的方法。 DB is designed to fetch data lying next to each other because of buffering and reading of hard-drive blogs ahead. DB旨在通过缓冲和读取前面的硬盘博客来获取彼此相邻的数据。 You can improve this solution using correct indexes and so on. 您可以使用正确的索引等来改进此解决方案。 What I'm saying is that sometimes it's better approach to fetch continuous drive segment from DB than making complex queries and than make searching for all nodes in java code. 我所说的是,有时候从DB获取连续驱动段比制作复杂查询更好,而不是在java代码中搜索所有节点。

    Note that one fetch of the whole tree (by root index id) can do DB within one DB read. 请注意,整个树的一次提取(通过根索引id)可以在一次DB读取中执行DB。 On the other hand, usually a select using nested query or using joins uses more reads, requires ids matching, maybe temporary table and so on. 另一方面,通常使用嵌套查询或使用连接的select使用更多读取,需要id匹配,可能是临时表等。 (index handling, locking, etc.) (索引处理,锁定等)

    You should definitely use various NoSQL DBs but also RDBMS. 你绝对应该使用各种NoSQL DB,还要使用RDBMS。

With SQLite 3.8.3 or later, you can use a query like the following to compute the subtree beginning at a specific node, and then get the leaves in that subtree: 使用SQLite 3.8.3或更高版本,您可以使用如下所示的查询来计算从特定节点开始的子树,然后获取该子树中的叶子:

WITH RECURSIVE subtree(comp_id, nodeId, parent, text)
AS (SELECT *
    FROM MyTable
    WHERE comp_id = 146 AND nodeId = 1  -- start node
    UNION ALL
    SELECT MyTable.*
    FROM MyTable
    JOIN subtree ON MyTable.comp_id = subtree.comp_id
                AND MyTable.parent  = subtree.nodeid)
SELECT *
FROM subtree
WHERE nodeid NOT IN (SELECT parent
                     FROM subtree)

With earlier SQLite versions, you would have to retrieve the nodes at each level by hand. 使用早期的SQLite版本,您必须手动检索每个级别的节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何获取树的所有叶节点? - How to get all leaf nodes of a tree? 如何获取Jtree Java中所有父节点的叶节点数 - How can i get the count of leaf nodes of all parent nodes in Jtree Java 如何使用递归获取二叉搜索树中的所有非叶节点? - How to get all non-leaf nodes in a binary search tree using recursion? 如何创建叶节点然后构建树 - How To Create Leaf Nodes And Then Build A Tree 如何为树节点分配唯一编号,以便可以从树叶中追溯父级? - How to assign unique numbers to the tree nodes so that from the tree leaf I can trace back the parents? java alogrithm:从树中的任何节点中找到满足特殊条件的前/后叶节点 - java alogrithm: find pre/next leaf node that meet special condition from any node in a tree 如何从子节点的值中获取父节点的名称? - How to get the name of the parent node from the values of child nodes? 遍历DOM树以获取(名称,值)属性对和叶节点 - Traversing a DOM tree to get (name,value) pairs of attributes and leaf nodes 如果有许多同名的父节点,如何从xml的父节点中选择所有子节点? - How to select all child nodes from a parent node from xml if there are many parents node with same name? 如何在zk中的动态树中选择父节点时选择所有子节点? - How to select all child nodes on selection of parent in a dynamic tree in zk?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM