private void DeleteCore(TernarySearchTreeNode <T> node, string key, int index)
        {
            if (node == null || !key.IsIndexValid(index))
            {
                return;
            }
            char @char = key[index];

            if (@char == node.Char)
            {
                if (index == key.Length - 1)
                {
                    if (node.IsEos)
                    {
                        size--;
                        node.IsEos = false;
                    }
                    node.Value = default(T);
                    return;
                }
                DeleteCore(node.Equal, key, index + 1);
            }
            else if (@char < node.Char)
            {
                DeleteCore(node.Left, key, index);
            }
            else
            {
                DeleteCore(node.Right, key, index);
            }
        }
        private TernarySearchTreeNode <T> SearchCore(TernarySearchTreeNode <T> node, string key, int index)
        {
            if (node == null || !key.IsIndexValid(index))
            {
                return(null);
            }
            char @char = key[index];

            if (@char == node.Char)
            {
                if (index == key.Length - 1)
                {
                    return(node.IsEos ? node : null);
                }
                return(SearchCore(node.Equal, key, index + 1));
            }
            else if (@char < node.Char)
            {
                return(SearchCore(node.Left, key, index));
            }
            else
            {
                return(SearchCore(node.Right, key, index));
            }
        }
 public void Insert(string key, T tag)
 {
     Guard.IsNotNull(key, nameof(key));
     if (key.IsEmpty())
     {
         return;
     }
     root = InsertCore(root, key, 0, tag);
 }
        protected override IEnumerator <KeyValuePair <string, T> > CreateEnumerator()
        {
            Stack <TernarySearchTreeNode <T> > stack = new Stack <TernarySearchTreeNode <T> >();
            StringBuilder stringBuilder = new StringBuilder(32);

            TernarySearchTreeNode <T> node = root;

            while (true)
            {
                while (node != null)
                {
                    stack.Push(node);
                    node = node.Left;
                }
                if (stack.IsEmpty)
                {
                    yield break;
                }
                node = stack.Peek();
                if (node != null)
                {
                    stringBuilder.Append(node.Char);
                    if (node.IsEos)
                    {
                        yield return(new KeyValuePair <string, T>(stringBuilder.ToString(), node.Value));
                    }
                    stack.Push(null);
                    node = node.Equal;
                }
                else
                {
                    stringBuilder.RemoveLastChar();
                    stack.Pop();
                    node = stack.Pop().Right;
                }
            }
        }
        private TernarySearchTreeNode <T> InsertCore(TernarySearchTreeNode <T> node, string key, int index, T tag)
        {
            if (!key.IsIndexValid(index))
            {
                return(null);
            }
            if (node == null)
            {
                node = new TernarySearchTreeNode <T>(key[index]);
            }
            char @char = key[index];

            if (@char == node.Char)
            {
                if (index == key.Length - 1)
                {
                    if (!node.IsEos)
                    {
                        node.IsEos = true;
                        node.Value = tag;
                        size++;
                    }
                    return(node);
                }
                node.Equal = InsertCore(node.Equal, key, index + 1, tag);
            }
            else if (@char < node.Char)
            {
                node.Left = InsertCore(node.Left, key, index, tag);
            }
            else
            {
                node.Right = InsertCore(node.Right, key, index, tag);
            }
            return(node);
        }
 public TernarySearchTree()
 {
     this.size = 0;
     this.root = null;
 }