有没有办法
我知道第一眼看上去没有意义,但我能以某种方式做到吗?
P
答案 0 :(得分:2)
对于一般树的InOrder遍历并没有多大意义。由于没有“Order”,您应该访问当前节点。 InOrder只对二叉树有意义。
要使InOrder对一般树有意义,您必须定义当前节点应该访问的顺序。由于唯一有意义的两个选择是首先访问当前节点(这是预订)或者最后一次(这是后期订购)。因此,一般树的InOrder并没有多大意义。
当然,如果您的常规树具有特定结构,则InOrder可以有意义。如果你总是让前3个孩子离开而其他所有孩子都是对的,那么你的算法就像这样...
inorder(node)
if node == null then return
inorder(node.first)
inorder(node.second)
inorder(node.third)
visit(node)
foreach (remainingNode in RemainingNodes)
inorder(remainingNode)
通用代码作为扩展方法......
static public IEnumerable<Node<T>> InOrder<T>(this Node<T> thisNode)
{
var list = new List<Node<T>>();
IEnumerable<Node<T>> leftNodes;
IEnumerable<Node<T>> rightNodes;
if (thisNode.Children == null)
{
leftNodes = new List<Node<T>>();
rightNodes = new List<Node<T>>();
}
else
{
leftNodes = thisNode.Children.Take((int)Math.Ceiling(thisNode.Children.Count() / 2.0)).ToList();
rightNodes = thisNode.Children.Skip(leftNodes.Count()).ToList();
}
if (leftNodes.Any())
{
foreach (var child in leftNodes)
{
list.AddRange(child.InOrder());
}
}
list.Add(thisNode);
if (rightNodes.Any())
{
foreach (var child in rightNodes)
{
list.AddRange(child.InOrder());
}
}
return list;
}
答案 1 :(得分:1)
按顺序遍历要求按顺序访问节点
对于非二叉树,这种行为没有意义,因为没有左或右专用节点。正如凯文所说,只有真的才有意义执行订单前或订单后的遍历;但是,如果要执行In-Order-esque遍历,则可以访问一半的子节点,此节点,然后访问另一半。但这并非真正符合有序遍历的精神。
例如,假设您的节点有5个孩子。这将使顺序遍历:
(仅仅是为了争论。从技术上讲,孩子3,这可以交换,但会出现同样的问题)
如果删除子5,则顺序遍历为:
并且固有顺序已经改变。
但是,如果你要维护两个孩子列表:一个是你的leftChildren
而另一个是rightChildren
,那么有序遍历会像在二进制中那样有意义。树。但是,如何选择哪个孩子在哪个列表中完全是另一个问题。
编辑:既然看起来你想要继续这样做,你可以用这样的东西来做:
public IEnumerable<Node<T>> InOrder()
{
if (Children != null)
{
for (int i = 0; i < Children.length; i++)
{
if (i == Children.length / 2)
{
yield return this;
}
foreach (var node in Children[i].InOrder())
{
yield return node;
}
}
}
}