C# 如何在树中找到下一个节点?
问题是这样的: 我们有一个使用类节点构建的树,其中类的实例表示树中的一个节点。为简单起见,该节点有一个int类型的数据字段。 您的任务是编写扩展方法NodeExtensions.Next()来查找树中的下一个元素。您可以根据需要编写任意多个helper方法,但不要更改扩展方法NodeExtensions.Next()的签名 我有一个节点类:C# 如何在树中找到下一个节点?,c#,algorithm,data-structures,graph,tree,C#,Algorithm,Data Structures,Graph,Tree,问题是这样的: 我们有一个使用类节点构建的树,其中类的实例表示树中的一个节点。为简单起见,该节点有一个int类型的数据字段。 您的任务是编写扩展方法NodeExtensions.Next()来查找树中的下一个元素。您可以根据需要编写任意多个helper方法,但不要更改扩展方法NodeExtensions.Next()的签名 我有一个节点类: public class Node { private List<Node> _children; public Node(i
public class Node
{
private List<Node> _children;
public Node(int data, params Node[] nodes)
{
Data = data;
AddRange(nodes);
}
public Node Parent { get; set; }
public IEnumerable<Node> Children
{
get
{
return _children != null
? _children
: Enumerable.Empty<Node>();
}
}
public int Data { get; private set; }
public void Add(Node node)
{
Debug.Assert(node.Parent == null);
if (_children == null)
{
_children = new List<Node>();
}
_children.Add(node);
node.Parent = this;
}
public void AddRange(IEnumerable<Node> nodes)
{
foreach (var node in nodes)
{
Add(node);
}
}
public override string ToString()
{
return Data.ToString();
}
}
我尝试的代码:
public static Node Next(this Node node)
{
var newNode = NextLargerElement(node, node.Data);
return newNode;
}
public static Node res;
public static Node NextLargerElementUtil(Node root, int x)
{
if (root == null)
return null;
if (root.Data > x)
if ((res == null || (res).Data > root.Data))
res = root;
foreach (var children in root.Children)
{
NextLargerElementUtil(children, x);
}
return res;
}
static Node NextLargerElement(Node root, int x)
{
res = null;
NextLargerElementUtil(root, x);
return res;
}
下面是一个测试案例:
[Test]
public void Test()
{
// Test tree:
//
// 1
// +-2
// +-3
// +-4
// +-5
// +-6
// +-7
//
var root = new Node(
1,
new Node(
2,
new Node(3),
new Node(4)),
new Node(
5,
new Node(6),
new Node(7)));
// Expected output:
//
// 1
// 2
// 3
// 4
// 5
// 6
// 7
//
var n = root;
while (n != null)
{
Console.WriteLine(n.Data);
n = n.Next();
}
// Test
//
n = root;
Assert.AreEqual(1, n.Data);
n = n.Next();
Assert.AreEqual(2, n.Data);
n = n.Next();
Assert.AreEqual(3, n.Data);
n = n.Next();
Assert.AreEqual(4, n.Data);
n = n.Next();
Assert.AreEqual(5, n.Data);
n = n.Next();
Assert.AreEqual(6, n.Data);
n = n.Next();
Assert.AreEqual(7, n.Data);
n = n.Next();
Assert.IsNull(n);
}
您可以使用
Equals
在树中回溯当前节点位置,并返回其父节点的下一个子节点(如果有),如果没有,则需要回溯当前节点父节点位置,依此类推:
public static Node Next(this Node node)
{
if(node.Children != null && node.Children.Any())
{
return node.Children.First();
}
// "backtracking", also can be done recursively
var parent = node.Parent;
while(parent != null)
{
var returnNext = false; // return next element in Children if current is node
foreach (var element in parent.Children)
{
if(returnNext)
{
return element;
}
if(element == node)
{
returnNext = true;
node = parent; // to find parent's position if there is no next child
}
}
parent = parent.Parent;
}
return null;
}
@鲁弗斯对不起,如果你有这样的印象,我不是故意的。我对数据结构有点迷茫。我用我尝试过的代码进行了编辑。我不会假设节点数据值已排序。Next()需要返回第一个子项或下一个兄弟项,或者继续搜索父项的兄弟项,在没有父项时停止。要找到一个兄弟姐妹,你必须跳过父母的孩子,直到你找到自己,然后把下一个孩子还给他。@GuillemSolerSuetta很乐意帮忙!
public static Node Next(this Node node)
{
if(node.Children != null && node.Children.Any())
{
return node.Children.First();
}
// "backtracking", also can be done recursively
var parent = node.Parent;
while(parent != null)
{
var returnNext = false; // return next element in Children if current is node
foreach (var element in parent.Children)
{
if(returnNext)
{
return element;
}
if(element == node)
{
returnNext = true;
node = parent; // to find parent's position if there is no next child
}
}
parent = parent.Parent;
}
return null;
}