将树数据结构保留在一个递归表中的最佳方法是什么

时间:2018-08-16 13:42:12

标签: sql sql-server algorithm data-structures tree

这是我的数据结构,看起来像一棵节点树,我将所有节点保存在一个递归表中:

Id   | Name    | ParentId  | Level
-----------------------------------
1    | Node1   | NULL      |  1
2    | Node2   | NULL      |  1
3    | Node3   | 1         |  2
4    | Node4   | 1         |  2
5    | Node5   | 3         |  3
6    | Node6   | 3         |  3
7    | Node7   | 3         |  3
8    | Node8   | 4         |  3
9    | Node9   | 6         |  4
10   | Node10  | 6         |  4
11   | Node11  | 8         |  4
12   | Node12  | 10        |  5

我遇到的问题是检索一个Node的子代和父代执行得不是很好,我试图调用递归函数来获取子代和父代。例如Node6

retrieveAllChildrenof(6){} -> return 9,10,12;

retrieveAllParentsof(6){} -> return 3,1;

所以我只是想添加一个新列以避免递归函数,就像这样:

Id   | Name    | ParentId  | Level  | Trace
---------------------------------------------
1    | Node1   | NULL      |  1     |  1
2    | Node2   | NULL      |  1     |  2
3    | Node3   | 1         |  2     |  1-3
4    | Node4   | 1         |  2     |  1-4
5    | Node5   | 3         |  3     |  1-3-5
6    | Node6   | 3         |  3     |  1-3-6
7    | Node7   | 3         |  3     |  1-3-7
8    | Node8   | 4         |  3     |  1-4-8
9    | Node9   | 6         |  4     |  1-3-6-9
10   | Node10  | 6         |  4     |  1-3-6-10
11   | Node11  | 8         |  4     |  1-4-8-11
12   | Node12  | 10        |  5     |  1-3-6-10-12

现在有了跟踪字段,我可以将孩子和父母检索为:

retrieveAllChildrenof(6){} -> 
//Trace(6) = 1-3-6; GetAllNodesThatStartWithTrace(1-3-6) => 9,10,12;

retrieveAllParentsof(6){} -> //Trace(6) = 1-3-6; GetNodesIdsIn(1-3); => 1,3;

我知道用逗号或破折号分隔的数据很难处理,但是有没有更好的方法可以在节点中导航并找到孩子和父母,有什么建议吗?

更新 目前,对于递归函数,我这样使用: CTE Recursion to get tree hierarchy

1 个答案:

答案 0 :(得分:0)

如果树很少改变,则可以进行深度优先搜索,对到达的节点进行编号。节点的后代具有连续的编号,紧接在分配给该节点的编号之后,并且您可以使用一列来记录每个节点的编号,并使用一列来记录其最后一个后代的编号。然后,通过查找节点的编号,最后一个后代的编号,并检索所有在这两个节点之间具有编号的行,来检索该节点的所有后代。