相关疑难解决方法(0)

将平台解析成树的最有效/优雅的方法是什么?

假设您有一个存储有序树层次结构的平面表:

Id   Name         ParentId   Order
 1   'Node 1'            0      10
 2   'Node 1.1'          1      10
 3   'Node 2'            0      20
 4   'Node 1.1.1'        2      10
 5   'Node 2.1'          3      10
 6   'Node 1.2'          1      20
Run Code Online (Sandbox Code Playgroud)

这是我们所拥有的图表[id] Name.根节点0是虚构的.

                       [0] ROOT
                          /    \ 
              [1] Node 1          [3] Node 2
              /       \                   \
    [2] Node 1.1     [6] Node 1.2      [5] Node 2.1
          /          
 [4] Node 1.1.1

您将使用什么简约方法将其输出为HTML(或文本,就此而言)作为正确排序,正确缩进的树?

进一步假设你只有基本的数据结构(数组和散列图),没有带有父/子引用的花哨对象,没有ORM,没有框架,只有你的双手.该表表示为结果集,可以随机访问.

伪代码或普通英语是可以的,这纯粹是一个概念性的问题.

额外问题:在RDBMS中存储这样的树结构是否有根本更好的方法?


编辑和补充

回答一个评论者(Mark Bessey的)问题:根节点不是必需的,因为它永远不会被显示.ParentId = 0是表示"这些是顶级"的惯例.Order列定义了如何对具有相同父节点的节点进行排序.

我所谈到的"结果集"可以被描绘成一组哈希图(保留在该术语中).因为我的例子意味着已经存在.有些答案会加倍努力并首先构建它,但那没关系.

树可以任意深.每个节点可以有N个子节点.不过,我并没有考虑到"数百万条目".

不要将我选择的节点命名('Node 1.1.1')误认为是依赖的东西.节点同样可以称为"Frank"或"Bob",不暗示命名结构,这只是为了使其可读. …

sql algorithm tree recursion hierarchical-data

508
推荐指数
8
解决办法
11万
查看次数

SQL - 如何存储和导航层次结构?

您在数据库中建模和检索分层信息的方式有哪些?

sql sql-server oracle database-design hierarchy

46
推荐指数
4
解决办法
3万
查看次数

如何构建数据库以进行快速节点访问

我正在寻找一种方法来构建数据库与VirtualTreeView和SQLite数据库,以便快速检索数据.使用VirtualTreeView有一个OnNodeInit事件,但它并不总是适用于此目的.

数据从Usenet新闻组中获取,需要进行线程化.对线程有用的数据是post id(int64,也是主键),引用(引用线程中先前帖子的字符串).

程序在引用中搜索字符串并确定它应该在哪个postid.因此,例如post id = 1234,则下一篇文章可能是1235,然后1236可能是对1234的回复.

这是一个可能的数据库示例:

post id    references    parent id
  1234      .... ....       0
  1235      .... ....       0
  1236      .... ....      1234
Run Code Online (Sandbox Code Playgroud)

所以现在这就是它现在的样子.

现在,问题是如何构建此数据以加快检索速度.如果只有一个根节点,我可以根据数据库条目分配RootNodeCount,然后在OnNodeInit中按要求逐个读取它们.当有子节点时,我需要以某种方式重新排列数据库,以便它知道如何更快地获取子节点,具体取决于打开哪个节点.

我正在考虑分配附加字段"has_subnodes",其中包含以下子节点的ID.单击节点时,它将读取该节点和每个链接节点.

你将如何组织这个数据库,以便在OnNodeInit中很好地阅读它,或者你会使用那个事件吗?也可以使用AddChildNoInit()方法启动节点.欢迎任何想法或指示.

更新(以及我如何解决)

这里提供了一些非虚拟视图相关信息: 在数据库中实现分层数据结构

我最终做的是使用Modified Preorder Tree Traversal在数据库中存储有关节点的信息,并且每次首先请求某个节点时:

a)在内部缓存中查找它基本上与VirtualTreeView结构保持相同的结构.

b)如果在缓存中找到,则删除此缓存条目(它永远不会超过100个项目)

c)如果未找到,则在缓存中添加额外的100个项目(从请求的节点向上50个,向下50个).如果需要,此课程数可以修改为500或1000个项目.还有一些额外的检查可以查看需要读取多少上/下来以避免读取过多的重复条目.

d)如果我需要更高的速度,我可以应用额外的技术 - 根据用户滚动虚拟视图的数量从数据库加载节点 - 类似于std :: vector如何分配内存 - 首先我只加载100个节点,然后如果用户滚动了很多,我加载200,然后400等...越多的用户滚动加载整个树的速度越快,但如果他/她从不滚动,仍然不加载它.

这样,永远不会从数据库加载从未见过的节点.(当它经过点高速缓存为空,从盘需要更多的数据,偶尔短的延迟)和用于与箭头按钮/键滚动它工作正常用于与鼠标滚轮滚动.将滚动条拖动到某个位置(例如从底部到中间)时速度会慢一些,但由于无法立即从磁盘中获取数据,因此可以预期.

最好是我在加载之前预先确定要用于缓存/项目的内存量,滚动速度越快但当然如果数据从未显示则会占用更多内存.

delphi sqlite c++builder hierarchical-data virtualtreeview

5
推荐指数
1
解决办法
2650
查看次数

树状数据结构(用于VirtualTreeview)

正如Rob Kennedy先生所建议的那样,我已经到了需要停止将数据存储在VCL组件中并具有"基础数据结构"的地步.

首先,这个问题是关于"我如何建立基础数据结构".:)

我的层次结构由2级节点组成.

现在,我通过循环根节点来完成我的东西,其中我循环通过rootnode的子节点,以获得我需要的东西(数据).我希望能够将所有数据存储在所谓的底层数据结构中,以便我可以使用线程轻松修改条目(我想我能够做到这一点?)

但是,当循环遍历我的条目(现在)时,结果取决于节点的Checkstate - 如果我使用的是底层数据结构,我怎么知道我的节点是否被检查,当我的数据结构循环通过时,而不是我的节点?

假设我想使用2个级别.

这将是父母:

TRoot = Record
  RootName : String;
  RootId : Integer;
  Kids : TList; //(of TKid)
End;
Run Code Online (Sandbox Code Playgroud)

那孩子:

TKid = Record
  KidName : String;
  KidId : Integer;
End;
Run Code Online (Sandbox Code Playgroud)

这基本上就是我现在所做的.评论说这不是最好的解决方案,所以我愿意接受建议.:)

我希望你理解我的问题.:)

谢谢!

delphi tree virtualtreeview data-structures

2
推荐指数
1
解决办法
5632
查看次数