找到空子项

时间:2016-06-21 09:06:18

标签: c#

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,是否有另一种方法返回所有空对象而不进行迭代?

3 个答案:

答案 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;
}