Csharp/C#教程:用于查找非父/祖父/ /等或子/孙等的所有链接对象的算法分享


用于查找非父/祖父/ /等或子/孙等的所有链接对象的算法

我有一个名为Device的对象。 Device可以有一个父 DeviceDevice也可以有n个子Devices

我有一个下拉列表,显示所有可选Devices 。 我可以很容易地获得数据库中的所有Devicesdb.Devices

层次结构可以是无限级别的。

我需要让所有不在树中给定Device之上或之下的Device 。 基本上我要求与给定Device无关的Device (父母/祖父母/祖父母/祖父母/等或儿童/孙子/曾孙子等)。 我还需要从列表中排除给定的Device

做这个的最好方式是什么? 我应该使用递归吗?

(我使用C#和Entity Framework与SQL Server数据库,所以我可以使用Linq To SQL或使用模型本身。)

我的方法是首先获得设备D所有兄弟姐妹:

 P = parent of the device sibs = {all children of P that are not D} 

d in sibs中任何d in sibs任何后代都与D无关。 继续走上家谱:

 G = grandparent of the device sibs = sibs union {all children of G that are not P} 

继续这样,集合sibs及其所有后代都是你所追求的集合。

在伪代码中:

 D = device; siblings = {}; while (D has parent) { P = parent(D); siblings = siblings union (children(P)  D); D = P; } return descendants(siblings); 

同意Denis – 这取决于您的数据的存储方式。

我建议您使用TSQL HierarchyId数据类型实现层次结构 。 然后,您可以使用IsDescendent非常轻松地检查行是否是另一行的后代

 DECLARE @searchId HierarchyId -- select your id SELECT @searchId = HierarchyId FROM Devices WHERE DeviceId = 1 SELECT * FROM Devices WHERE -- not children DeviceHierarchyId.IsDescendantOf(@seachId) = 0 -- not parents AND @searchId.IsDescendantOf(DeviceHierarchyId) = 0 

编辑

要简要说明HierarchyId数据类型及其工作原理,请考虑每个项目在根节点下的层次结构中都有一个位置。 (如果您有多个自然根,则将每个根置于超根之下)。 每个hierarchyid列存储item的完整层次结构位置。 例如

 Id | ParentId | HierarchyId 1 | null | 1 2 | 1 | 12 3 | 1 | 13 4 | 3 | 134 

等等。 要检查项是否是另一个项的子项,只需检查hierarchyId是否包含在另一行的hierarchyId中 – 例如4是3的子项,因为整个13包含在其hierarchyId 134 ,但是4不是2的子元素,因为12不包含在hierarchyId中。

要查看itemA是否是itemB的项,请检查itemB是否为itemA的子项。

最后,您实际上不需要进行任何比较。 TSQL HierarchyId类型包含许多方法,其中一个方法是我在上面突出显示的IsDescendantOf方法。 因此像hierarcyId1.IsDescendantOf(hierarchyId2)这样的用法会执行我在此处描述的那种检查。 hierarchyIds是二进制的,并且在数据库中非常快速地进行比较。

在处理数据库层次结构时,我会尽可能使用hierarchyId。

如果您有父母的索引,您可以尝试

 select * from devices as child where exists(select null from devices as parent where parent.id = child.parent) 

我的SQL并不完美,但这是我会使用的基本方法。

我的下意识算法解决方案是一种“标记 – 扫描”类型的解决方案(来自垃圾收集器理论)。

https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)#Na.C3.AFve_mark-and-sweep

基本上,您遍历整个设备层次结构并标记“可追踪”的设备,这意味着它们可以通过另一个设备“使用递归”“到达”。

任何没有标记的东西,你都会“扫”出GC。 在您的情况下,任何未标记的是您正在寻找的集合。

这取决于您如何将树存储在数据库中。 有嵌套集模型 ,允许直接在数据库中进行此类查询。

上述就是C#学习教程:用于查找非父/祖父/ /等或子/孙等的所有链接对象的算法分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/957570.html

(0)
上一篇 2021年11月21日
下一篇 2021年11月21日

精彩推荐