2

There is an excellent article on MSDN about binary trees and how to create a custom binary tree here

Question

The code is below.It is a bit long but I am only pasting it for reference.(just a glance will tell you all).

My question actually is that if I do implement a custom binary tree like this below, should I first be defining an interface for each Node, NodesList, BinaryTree, BinaryTreeNode (4 classes)for later unit testing , or is it not needed in this case. I see that numerous collections in .net implement IEnumerable, should I do the same or is there any reason that I do not need to do that here?

public class Node<T>
{
        // Private member-variables
        private T data;
        private NodeList<T> neighbors = null;

        public Node() {}
        public Node(T data) : this(data, null) {}
        public Node(T data, NodeList<T> neighbors)
        {
            this.data = data;
            this.neighbors = neighbors;
        }

        public T Value
        {
            get
            {
                return data;
            }
            set
            {
                data = value;
            }
        }

        protected NodeList<T> Neighbors
        {
            get
            {
                return neighbors;
            }
            set
            {
                neighbors = value;
            }
        }
    }
}

The Node Class

public class NodeList<T> : Collection<Node<T>>
{
    public NodeList() : base() { }

    public NodeList(int initialSize)
    {
        // Add the specified number of items
        for (int i = 0; i < initialSize; i++)
            base.Items.Add(default(Node<T>));
    }

    public Node<T> FindByValue(T value)
    {
        // search the list for the value
        foreach (Node<T> node in Items)
            if (node.Value.Equals(value))
                return node;

        // if we reached here, we didn't find a matching node
        return null;
    }
}

and finally

public class BinaryTreeNode<T> : Node<T>
{
    public BinaryTreeNode() : base() {}
    public BinaryTreeNode(T data) : base(data, null) {}
    public BinaryTreeNode(T data, BinaryTreeNode<T> left, BinaryTreeNode<T> right)
    {
        base.Value = data;
        NodeList<T> children = new NodeList<T>(2);
        children[0] = left;
        children[1] = right;

        base.Neighbors = children;
    }

    public BinaryTreeNode<T> Left
    {
        get
        {
            if (base.Neighbors == null)
                return null;
            else
                return (BinaryTreeNode<T>) base.Neighbors[0];
        }
        set
        {
            if (base.Neighbors == null)
                base.Neighbors = new NodeList<T>(2);

            base.Neighbors[0] = value;
        }
    }

    public BinaryTreeNode<T> Right
    {
        get
        {
            if (base.Neighbors == null)
                return null;
            else
                return (BinaryTreeNode<T>) base.Neighbors[1];
        }
        set
        {
            if (base.Neighbors == null)
                base.Neighbors = new NodeList<T>(2);

            base.Neighbors[1] = value;
        }
    }
}


public class BinaryTree<T>
{
   private BinaryTreeNode<T> root;

   public BinaryTree()
   {
      root = null;
   }

   public virtual void Clear()
   {
      root = null;
   }

   public BinaryTreeNode<T> Root
   {
      get
      {
         return root;
      }
      set
      {
         root = value;
      }
   }
}
4

1 回答 1

1

不是答案,评论太长了:

公开集合总是一个好主意,IEnumerable因为在这种情况下您可以轻松地应用 LINQ 查询。

二叉树本身毫无用处,内部细节(节点)更不有趣。因此,将内部细节暴露为接口可能不会有用。将二叉树公开为特定的接口也可能是矫枉过正——如果你需要它来表示一些排序的结构IList/ICollection或者IDictionary可能就足够了。

请注意,如果您正在构建二叉树作为其他几个有趣集合的基础,您可能会考虑接口,但它应该由测试特定代码片段的需要驱动。

于 2013-08-30T22:58:08.367 回答