C# 如何遍历具有多个级别的树以查找当前元素的上一个和下一个元素?
如何在具有子列表的树中找到任何给定元素的上一个和下一个元素 范例 A. 1.1 AA 1.1.1 AAA 1.1.2 BBB 1.1.3 CCC 1.2 DD 如何获取1.1.3 CCC的上一个和下一个id?我只知道CCC在给定时刻的ID 我正在处理的真实示例是一个类别实体,它本身具有递归关联,因为它可以包含子类别。如果我在3级子类别中,我想知道上一个和下一个类别的ID 在我的视图网页中,我有一个所有类别的列表。当我点击一个类别时,我只知道它自己的id,但我也想得到上一个和下一个id 我使用了以下方法,但如果级别更高,这些方法不起作用:C# 如何遍历具有多个级别的树以查找当前元素的上一个和下一个元素?,c#,entity-framework,C#,Entity Framework,如何在具有子列表的树中找到任何给定元素的上一个和下一个元素 范例 A. 1.1 AA 1.1.1 AAA 1.1.2 BBB 1.1.3 CCC 1.2 DD 如何获取1.1.3 CCC的上一个和下一个id?我只知道CCC在给定时刻的ID 我正在处理的真实示例是一个类别实体,它本身具有递归关联,因为它可以包含子类别。如果我在3级子类别中,我想知道上一个和下一个类别的ID 在我的视图网页中,我有一个所有类别的列表。当我点击一个类别时,我只知道它自己的id,但我也想得到上一个和下一个id 我使用了以
private void GetNextCategoryID(PagedData<ShowQuestionViewModel> questionsPaged)
{
List<Category> categories = db.Category.Where(y => y.parrent_id == null).ToList();
categories.Sort(new CompareCategory());
List<ShowCategoriesViewModel> scvm = Mapper.Map<List<Category>, List<ShowCategoriesViewModel>>(categories);
for (int i = 0; i < scvm.Count; i++)
{
if (scvm[i].category_id == questionsPaged.CategoryID)
{
if (scvm[i].SubCategories != null && scvm[i].SubCategories.Count > 0)
{
questionsPaged.NextCategory_ID = scvm[i].SubCategories.First().category_id;
break;
}
try
{
questionsPaged.NextCategory_ID = scvm[i + 1].category_id;
break;
}
catch (ArgumentOutOfRangeException ex)
{
questionsPaged.NextCategory_ID = 0;
break;
}
}
else if (scvm[i].SubCategories != null)
{
for (int q = 0; q < scvm[i].SubCategories.Count; q++)
{
if (scvm[i].SubCategories[q].category_id == questionsPaged.CategoryID)
{
try
{
questionsPaged.NextCategory_ID = scvm[i].SubCategories[q + 1].category_id;
break;
}
catch (ArgumentOutOfRangeException ex)
{
// Betyder at vi er kommet til den sidste kategori i rækken
// og at den endnu ikke har fundet en match
try
{
questionsPaged.NextCategory_ID = scvm[i + 1].category_id;
break;
}
catch (ArgumentOutOfRangeException eq)
{
// Dette betyder at den valgte underkategori kategori er den sidste i spørgeskemaet
questionsPaged.NextCategory_ID = 0;
break;
}
}
}
}
}
}
}
及
谢谢 理论上,您应该做的是:使用当前类别的id,遍历树,直到找到具有该id的节点。在这里,要找到后续节点,我假设后续节点位于右侧,您必须返回树:如果父节点有一个正确的子节点,则查找子树最左侧的节点,根位于该子节点,否则,将此推理递归地应用于父对象的父对象,依此类推 要查找前置节点,只需执行上述步骤,但检查父节点是否有左子节点,并查找该子树的righmost节点,或递归应用于父节点的父节点
// finds the successor of node
procedure successor(node)
{
// assuming you have the node for the id that you know.
// also I'm assuming you have some way to find its position
// in the child list
// if the parent has a child to the right
if(parent(node).children[position(node) + 1] != null)
{
return findLeftmost(parent(node).children[position(node) + 1]);
// find the leftmost node in the subtree rooted
// at the next sibling to the right
}
else
{
return successor(parent(node));
// move up the tree
}
}
// finds the leftmost leaf node of the (sub)tree rooted at node
procedure findLeftmost(node)
{
if(node.children.length == 0) // leaf node
{
return node;
}
else
{
return findLeftmost(node.children[0]);
// here I'm assuming the children are in the list from left to right,
// such that children[0] is the leftmost child.
}
}
我不太确定我是否理解你的问题,因此如果是这样的话,请提前道歉
在我看来,您的节点列表中有索引,并且您知道它的级别,因此您只需跳过视图中具有更高级别的上一个或下一个节点,即它们是子节点,直到您找到一个具有相同级别(因此为同级)或更低级别的节点,或者节点用尽,在这种情况下,该级别上没有兄弟节点。所以树节点包含一个类别,每个节点可以有任意数量的子节点,对吗?它实际上不是一棵树,而是一个列表,但我明白你的意思。我会努力让它发挥作用,然后再给你回复。除了类别在它们自己的孩子之前,所以去右边你只需要看看你自己的第一个孩子,或者顶级兄弟姐妹。在前面的左边,你仍然必须遵循这个逻辑。好的,它不是很详细,但它是一般的想法。我实际上没有列表中的索引,我只有元素的数据库ID,所以我也不知道它的级别。我可以在我的网站上看到级别,因为它创建了一个树,但当我点击类别时,我所拥有的只是它的id。
// finds the successor of node
procedure successor(node)
{
// assuming you have the node for the id that you know.
// also I'm assuming you have some way to find its position
// in the child list
// if the parent has a child to the right
if(parent(node).children[position(node) + 1] != null)
{
return findLeftmost(parent(node).children[position(node) + 1]);
// find the leftmost node in the subtree rooted
// at the next sibling to the right
}
else
{
return successor(parent(node));
// move up the tree
}
}
// finds the leftmost leaf node of the (sub)tree rooted at node
procedure findLeftmost(node)
{
if(node.children.length == 0) // leaf node
{
return node;
}
else
{
return findLeftmost(node.children[0]);
// here I'm assuming the children are in the list from left to right,
// such that children[0] is the leftmost child.
}
}