Skip to content

Instantly share code, notes, and snippets.

@kpol
Last active February 11, 2018 22:49
Show Gist options
  • Save kpol/916b53d2867752e7796e149f4ac860e1 to your computer and use it in GitHub Desktop.
Save kpol/916b53d2867752e7796e149f4ac860e1 to your computer and use it in GitHub Desktop.
BinarySearchTree C# implementation
using System;
using System.Collections;
using System.Collections.Generic;
namespace ConsoleApplication10
{
public class BinarySearchTreeSet<T> : ICollection<T>
{
private readonly IComparer<T> _comparer;
private Node _root;
public BinarySearchTreeSet() : this(Comparer<T>.Default)
{
}
public BinarySearchTreeSet(IComparer<T> comparer)
{
_comparer = comparer;
}
public void Add(T item)
{
if (_root == null)
{
_root = new Node(item);
Count++;
return;
}
InsertIteratively(item);
}
public void Clear()
{
throw new NotImplementedException();
}
public bool Contains(T item)
{
return Search(item) != null;
}
internal T Get(T item)
{
var result = Search(item);
return result != null ? result.Key : default(T);
}
public void CopyTo(T[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public bool Remove(T key)
{
throw new NotImplementedException();
}
public int Count { get; private set; }
public bool IsReadOnly => false;
private Node InsertRecursively(Node node, T key)
{
if (node == null)
{
node = new Node(key);
Count++;
}
else if (_comparer.Compare(key, node.Key) < 0)
{
node.Left = InsertRecursively(node.Left, key);
}
else if (_comparer.Compare(key, node.Key) > 0)
{
node.Right = InsertRecursively(node.Right, key);
}
else
{
throw new InvalidOperationException($"Node with Key: {key} already exists.");
}
return node;
}
private void InsertIteratively(T key)
{
var node = _root;
while (true)
{
if (_comparer.Compare(key, node.Key) == 0)
{
throw new InvalidOperationException($"Node with Key: {key} already exists.");
}
if (_comparer.Compare(key, node.Key) < 0)
{
if (node.Left == null)
{
node.Left = new Node(key);
break;
}
node = node.Left;
}
else
{
if (node.Right == null)
{
node.Right = new Node(key);
break;
}
node = node.Right;
}
}
Count++;
}
private Node Search(T key)
{
var node = _root;
while (node != null)
{
if (_comparer.Compare(key, node.Key) == 0)
{
return node;
}
node = _comparer.Compare(key, node.Key) < 0 ? node.Left : node.Right;
}
return null;
}
public IEnumerable<T> InOrder()
{
var stack = new Stack<Node>();
var currentNode = _root;
while (currentNode != null || stack.Count > 0)
{
if (currentNode != null)
{
stack.Push(currentNode);
currentNode = currentNode.Left;
}
else
{
currentNode = stack.Pop();
yield return currentNode.Key;
currentNode = currentNode.Right;
}
}
}
public IEnumerable<T> PreOrder()
{
var stack = new Stack<Node>();
var currentNode = _root;
while (currentNode != null || stack.Count > 0)
{
if (currentNode != null)
{
yield return currentNode.Key;
stack.Push(currentNode.Right);
currentNode = currentNode.Left;
}
else
{
currentNode = stack.Pop();
}
}
}
public IEnumerator<T> GetEnumerator()
{
return PreOrder().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
private class Node
{
public Node(T key)
{
Key = key;
}
public T Key { get; }
public Node Left { get; set; }
public Node Right { get; set; }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment