Пример #1
0
        private T[] getValue(TernarySearchTreeNode <T> next)
        {
            var result = new Stack <T>();

            result.Push(next.Value);

            while (next.Parent != null && !next.Parent.Value.Equals(default(T)))
            {
                next = next.Parent;
                result.Push(next.Value);
            }

            return(result.ToArray());
        }
Пример #2
0
        /// <summary>
        /// Insert a new record to this ternary search tree after finding the end recursively.
        /// </summary>
        private void insert(ref TernarySearchTreeNode <T> currentNode,
                            TernarySearchTreeNode <T> parent,
                            T[] entry, int currentIndex)
        {
            //create new node if empty
            if (currentNode == null)
            {
                currentNode = new TernarySearchTreeNode <T>(parent, entry[currentIndex]);
            }

            var compareResult = currentNode.Value.CompareTo(entry[currentIndex]);

            //current is greater? move left, move right otherwise
            //if current is equal then move center
            if (compareResult > 0)
            {
                //move left
                var left = currentNode.Left;
                insert(ref left, parent, entry, currentIndex);
                currentNode.Left = left;
            }
            else if (compareResult < 0)
            {
                //move right
                var right = currentNode.Right;
                insert(ref right, parent, entry, currentIndex);
                currentNode.Right = right;
            }
            else
            {
                if (currentIndex != entry.Length - 1)
                {
                    //if equal we just skip to next element
                    var middle = currentNode.Middle;
                    insert(ref middle, currentNode, entry, currentIndex + 1);
                    currentNode.Middle = middle;
                }
                //end of word
                else
                {
                    if (currentNode.IsEnd)
                    {
                        throw new Exception("Item exists.");
                    }

                    currentNode.IsEnd = true;
                    return;
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Gathers all suffixes under this node appending with the given prefix
        /// </summary>
        private void gatherStartsWith(List <T[]> result, T[] prefix, TernarySearchTreeNode <T> node)
        {
            while (true)
            {
                if (node == null)
                {
                    result.Add(prefix);
                    return;
                }

                //end of word
                if (node.IsEnd)
                {
                    //append to end of prefix for new prefix
                    var newPrefix = new T[prefix.Length + 1];
                    Array.Copy(prefix, newPrefix, prefix.Length);
                    newPrefix[newPrefix.Length - 1] = node.Value;
                    result.Add(newPrefix);
                }

                if (node.Left != null)
                {
                    gatherStartsWith(result, prefix, node.Left);
                }

                if (node.Middle != null)
                {
                    //append to end of prefix for new prefix
                    var newPrefix = new T[prefix.Length + 1];
                    Array.Copy(prefix, newPrefix, prefix.Length);
                    newPrefix[newPrefix.Length - 1] = node.Value;

                    gatherStartsWith(result, newPrefix, node.Middle);
                }

                if (node.Right != null)
                {
                    node = node.Right;
                    continue;
                }

                break;
            }
        }
Пример #4
0
        /// <summary>
        /// Recursively visit until end of prefix and then gather all suffixes under it.

        /// </summary>
        private List <T[]> startsWith(TernarySearchTreeNode <T> currentNode, T[] searchPrefix, int currentIndex)
        {
            while (true)
            {
                if (currentNode == null)
                {
                    return(new List <T[]>());
                }

                var compareResult = currentNode.Value.CompareTo(searchPrefix[currentIndex]);
                //current is greater? move left, move right otherwise
                //if current is equal then move center
                if (compareResult > 0)
                {
                    //move left
                    currentNode = currentNode.Left;
                    continue;
                }

                if (compareResult < 0)
                {
                    //move right
                    currentNode = currentNode.Right;
                    continue;
                }

                //end of search Prefix, so gather all words under it
                if (currentIndex != searchPrefix.Length - 1)
                {
                    currentNode  = currentNode.Middle;
                    currentIndex = currentIndex + 1;
                    continue;
                }

                var result = new List <T[]>();

                gatherStartsWith(result, searchPrefix.ToList(), currentNode.Middle);

                return(result);
            }
        }
Пример #5
0
        /// <summary>
        /// Gathers all suffixes under this node appending with the given prefix
        /// </summary>
        private void gatherStartsWith(List <T[]> result, List <T> prefix, TernarySearchTreeNode <T> node)
        {
            while (true)
            {
                if (node == null)
                {
                    result.Add(prefix.ToArray());
                    return;
                }

                //end of word
                if (node.IsEnd)
                {
                    //append to end of prefix for new prefix
                    result.Add(prefix.Concat(new[] { node.Value }).ToArray());
                }

                if (node.Left != null)
                {
                    gatherStartsWith(result, prefix, node.Left);
                }

                if (node.Middle != null)
                {
                    //append to end of prefix for new prefix
                    prefix.Add(node.Value);
                    gatherStartsWith(result, prefix, node.Middle);
                    prefix.RemoveAt(prefix.Count - 1);
                }

                if (node.Right != null)
                {
                    node = node.Right;
                    continue;
                }

                break;
            }
        }
        /// <summary>
        /// Find if the record exist recursively
        /// </summary>
        /// <param name="currentNode"></param>
        /// <param name="entry"></param>
        /// <param name="currentIndex"></param>
        /// <returns></returns>
        private bool Contains(TernarySearchTreeNode <T> currentNode, T[] entry, int currentIndex)
        {
            //create new node if empty
            if (currentNode == null)
            {
                return(false);
            }

            //end of word, so return
            if (currentIndex == entry.Length - 1)
            {
                if (currentNode.IsEnd)
                {
                    return(true);
                }

                return(false);
            }

            var compareResult = currentNode.Value.CompareTo(entry[currentIndex]);

            //current is greater? move left, move right otherwise
            //if current is equal then move center
            if (compareResult > 0)
            {
                //move left
                return(Contains(currentNode.Left, entry, currentIndex));
            }
            else if (compareResult < 0)
            {
                //move right
                return(Contains(currentNode.Right, entry, currentIndex));
            }
            else
            {
                //if equal we just skip to next element
                return(Contains(currentNode.Middle, entry, currentIndex + 1));
            }
        }
Пример #7
0
        /// <summary>
        /// Find if the record exist recursively.
        /// </summary>
        private bool search(TernarySearchTreeNode <T> currentNode, T[] searchEntry, int currentIndex, bool isPrefixSearch)
        {
            while (true)
            {
                //create new node if empty
                if (currentNode == null)
                {
                    return(false);
                }

                //end of word, so return
                if (currentIndex == searchEntry.Length - 1)
                {
                    return(isPrefixSearch || currentNode.IsEnd);
                }

                var compareResult = currentNode.Value.CompareTo(searchEntry[currentIndex]);
                //current is greater? move left, move right otherwise
                //if current is equal then move center
                if (compareResult > 0)
                {
                    //move left
                    currentNode = currentNode.Left;
                    continue;
                }

                if (compareResult < 0)
                {
                    //move right
                    currentNode = currentNode.Right;
                    continue;
                }

                //if equal we just skip to next element
                currentNode  = currentNode.Middle;
                currentIndex = currentIndex + 1;
            }
        }
        /// <summary>
        /// recursively visit until end of prefix
        /// and then gather all suffixes under it
        /// </summary>
        /// <param name="currentNode"></param>
        /// <param name="searchPrefix"></param>
        /// <param name="currentIndex"></param>
        /// <returns></returns>
        private List <T[]> StartsWith(TernarySearchTreeNode <T> currentNode,
                                      T[] searchPrefix, int currentIndex)
        {
            if (currentNode == null)
            {
                return(new List <T[]>());
            }

            var compareResult = currentNode.Value.CompareTo(searchPrefix[currentIndex]);

            //current is greater? move left, move right otherwise
            //if current is equal then move center
            if (compareResult > 0)
            {
                //move left
                return(StartsWith(currentNode.Left, searchPrefix, currentIndex));
            }
            else if (compareResult < 0)
            {
                //move right
                return(StartsWith(currentNode.Right, searchPrefix, currentIndex));
            }
            else
            {
                //end of search Prefix, so gather all words under it
                if (currentIndex == searchPrefix.Length - 1)
                {
                    var result = new List <T[]>();

                    GatherStartsWith(result,
                                     searchPrefix, currentNode.Middle);

                    return(result);
                }
                //if equal we just skip to next element
                return(StartsWith(currentNode.Middle, searchPrefix, currentIndex + 1));
            }
        }
Пример #9
0
        /// <summary>
        /// Deletes a record from this TernarySearchTree after finding it recursively.
        /// </summary>
        private void delete(TernarySearchTreeNode <T> currentNode,
                            T[] entry, int currentIndex)
        {
            //empty node
            if (currentNode == null)
            {
                throw new Exception("Item not found.");
            }

            var compareResult = currentNode.Value.CompareTo(entry[currentIndex]);
            TernarySearchTreeNode <T> child;

            //current is greater? move left, move right otherwise
            //if current is equal then move center
            if (compareResult > 0)
            {
                //move left
                child = currentNode.Left;

                delete(child, entry, currentIndex);
                //delete if middle is not end
                //and we if have'nt deleted the node yet
                if (child.HasChildren == false &&
                    !child.IsEnd)
                {
                    currentNode.Left = null;
                }
            }
            else if (compareResult < 0)
            {
                //move right
                child = currentNode.Right;
                delete(child, entry, currentIndex);
                //delete if middle is not end
                //and we if have'nt deleted the node yet
                if (child.HasChildren == false &&
                    !child.IsEnd)
                {
                    currentNode.Right = null;
                }
            }
            else
            {
                if (currentIndex != entry.Length - 1)
                {
                    //if equal we just skip to next element
                    child = currentNode.Middle;
                    delete(child, entry, currentIndex + 1);
                    //delete if middle is not end
                    //and we if have'nt deleted the node yet
                    if (child.HasChildren == false &&
                        !child.IsEnd)
                    {
                        currentNode.Middle = null;
                    }
                }
                //end of word
                else
                {
                    if (!currentNode.IsEnd)
                    {
                        throw new Exception("Item not found.");
                    }

                    //remove this end flag
                    currentNode.IsEnd = false;
                    return;
                }
            }
        }
Пример #10
0
 internal TernarySearchTreeEnumerator(TernarySearchTreeNode <T> root)
 {
     this.root = root;
 }
Пример #11
0
 internal TernarySearchTreeNode(TernarySearchTreeNode <T> parent, T value)
 {
     Parent     = parent;
     this.Value = value;
 }