Objects that represent trees

前端 未结 4 1889
暖寄归人
暖寄归人 2020-12-05 07:41

Are there any objects in C# (or in .net) that represents a binary tree (or for curiosity) and n-ary tree?

I am not talking about presentation tree controls, but as m

4条回答
  •  Happy的楠姐
    2020-12-05 08:06

    My attempt at a simple (non-balancing) binary search tree.

    public sealed class BinarySearchTree : IEnumerable
    {
       private readonly IComparer _comparer;
       public BinaryTreeNode Root { get; private set; }
    
       public BinarySearchTree()
       {    
       }
    
       public BinarySearchTree(IEnumerable collection) : 
           this(collection, Comparer.Default)
       {
       }
    
       public BinarySearchTree(IEnumerable collection, IComparer comparer)
       {
           if (collection == null) throw new ArgumentNullException("collection");
           if (comparer == null) throw new ArgumentNullException("comparer");
    
           _comparer = comparer;
           foreach (var item in collection)
               Add(item);
       }
    
       public BinarySearchTree(BinaryTreeNode root)
       {
           Root = root;
       }
    
       public void Add(T val)   
       {    
           var newNode = new BinaryTreeNode(val);
           if (Root == null)
           {
               Root = newNode;
               return;
           }
    
           Add(Root, newNode);  
       }
    
       void Add(BinaryTreeNode root, BinaryTreeNode node)
       {
           if (_comparer.Compare(node.Value, root.Value) <= 0)
           {
               if (root.Left == null)
                   root.Left = node;
               else
                   Add(root.Left, node);
           }
           else //node.Value > root.Value
           {
               if (root.Right == null)
                   root.Right = node;
               else
                   Add(root.Right, node);   
           }
       }
    
       public bool Contains(T val)
       {
           return Contains(Root, val);
       }
    
       bool Contains(BinaryTreeNode node, T val)
       {
           if (node == null) 
               return false;
    
           var comparison = _comparer.Compare(val, node.Value);
           if (comparison == 0) //val = node.value
               return true;
           else if (comparison < 0) //val < node.Value
               return Contains(node.Left, val);
           else //val > node.Value
               return Contains(node.Right, val);
       }
    
       public T GetMinimum()
       {
           if (Root == null)
               return default(T);
    
           var node = Root;
           while (node.Left != null)
               node = node.Left;
    
           return node.Value;       
       }
    
       public T GetMaximum()
       {
           if (Root == null)
               return default(T);
    
           var node = Root;
           while (node.Right != null)
               node = node.Right;
    
           return node.Value;       
       }
    
       public IEnumerator GetEnumerator()
       {
           return new BinaryTreeEnumerator(Root);
       }
    
       IEnumerator IEnumerable.GetEnumerator()
       {
           return GetEnumerator();
       }
    }
    
    public sealed class BinaryTreeNode
    {
        public BinaryTreeNode Left {get; set;}
        public BinaryTreeNode Right {get; set;}      
        public T Value {get; private set;}
    
        public BinaryTreeNode(T val)
        {
            Value = val;
        }
    }
    
    public sealed class BinaryTreeEnumerator : IEnumerator
    {
        private Stack> _stack = new Stack>();
        public T Current { get; private set; }
    
        public BinaryTreeEnumerator(BinaryTreeNode root)
        {
            if (root == null)
                return; //empty root = Enumerable.Empty()
    
            PushLeftBranch(root);
        }
    
        public void Dispose()
        {
            _stack = null; //help GC
        }
    
        public bool MoveNext()
        {
            if (_stack.Count == 0)
                return false;
    
            var node = _stack.Pop();
            Current = node.Value;
    
            if (node.Right != null)
                PushLeftBranch(node.Right);
    
            return true;
        }
    
        private void PushLeftBranch(BinaryTreeNode node)
        {
            while (node != null)
            {
                _stack.Push(node);
                node = node.Left;
            }
        }
    
        public void Reset()
        {
            _stack.Clear();
        }
    
        object IEnumerator.Current
        {
            get { return Current; }
        }
    }
    

提交回复
热议问题