public class Node
{
public Node rightNode;
public Node bottomNode;
public double x_position;
public double z_position;
public double width;
public double length;
public bool isOccupied;
}
在此代码中,我有一个自引用属性rightNode
。
所以我的问题是,如何使用null
rightNode
确定所有节点。
var rootNode = this.rootNode;
while (rootNode != null)
{
rootNode = rootNode.right
}
到目前为止,我需要迭代所有分支以检查它是否为null,是否有另一种方法返回所有空对象而不进行迭代?
答案 0 :(得分:4)
您可以将所有具有null rightNode的节点存储在一个集合中。该集合将是静态的(即,对于所有节点只有一个)。 rightNode
必须成为一个属性:当它被设置为null时,节点将自己输入thr HashSet;如果它是非null,它将自己从中移除。
示例:
public class Node
{
// Added to store null nodes
public static HashSet<Node> _nullNodes = new HashSet<Node>();
Node _rightNode;
// Changed to property in order to perform
// insertion/deletion from set of null nodes
public Node rightNode
{
get { return _rightNode; }
set
{ // we don't care about redundant add/remove.
if (value == null) { _nullNodes.Add(this); }
else { _nullNodes.Remove(this); }
_rightNode = value;
}
}
public Node bottomNode;
public double x_position;
public double z_position;
public double width;
public double length;
public bool isOccupied;
// Added for identification
public object tag;
public override string ToString()
{
return tag == null ? "Un-tagged" : tag.ToString();
}
}
class Program
{
static void Main(string[] args)
{
Node n = new Node();
n.tag = "node 1";
n.rightNode = new Node();
n.rightNode.tag = "node 2, null right";
n.rightNode.rightNode = null;
Console.Out.WriteLine("Null nodes: ");
// should print one node
foreach (var node in Node._nullNodes)
{
Console.Out.WriteLine(" " + node);
}
n.rightNode.rightNode = new Node();
// should print no node any more (we replaced null with a node).
Console.Out.WriteLine("Null nodes: ");
foreach (var node in Node._nullNodes)
{
Console.Out.WriteLine(" " + node);
}
}
示例会话:
Null nodes:
node 2, null right
Null nodes:
答案 1 :(得分:3)
一种可能性是创建一个属性,以适当的序列化方式返回整个树,比如inorder,如下所示。
public IEnumerable<Node> InOrder
{
get
{
if (null != bottomNode)
foreach (var bNode in bottomNode.InOrder)
yield return bNode;
yield return this;
if (null != rightNode)
foreach (var rNode in rightNode.InOrder)
yield return rNode;
}
}
通过此属性,可以使用Linq访问树,并且可以按如下方式获取所需的节点,其中root
是树的根。
var DesiredNodes = root.InOrder.Where(iNode => null == iNode.rightNode);
对于Linq-ish倾向的更多,该属性可以重写如下。
public IEnumerable<Node> InOrder
{
get
{
return (null == bottomNode ? new Node[]{} : bottomNode.InOrder)
.Concat(new Node[]{this})
.Concat(null == rightNode ? new Node[]{} : rightNode.InOrder);
}
}
答案 2 :(得分:3)
如果节点树没有循环,则递归很容易。
public List<Node> AllWrong(Node root)
{
List<Node> wrongs = new List<Node>();
if (root == null)
return wrongs;
if (root.RightNode == null)
{
// This is not right
wrongs.Add(root);
}
// Recursively search - assumes this is a tree
wrongs.AddRange(AllWrong(root.rightNode));
wrongs.AddRange(AllWrong(root.bottomNode));
return wrongs;
}