示例#1
0
        public bool Insert(T data)
        {
            /* if (!(data is ValueType) && EqualityComparer<T>.Default.Equals(data, default(T)) )
             * {
             *  return false;
             * }
             * else */if (m_Root == m_Bottom)
            {
                // create root node
                m_Root = CreateNode(data);
                return(true);
            }
            else
            {
                Node currentNode      = m_Root;
                Node parent           = null;
                int  comparisonResult = 1;  // initial value for loop condition to hold

                // store traversal history in stack
                Stack <TraversalHistory> nodeStack = new Stack <TraversalHistory>((int)Math.Ceiling(Math.Log(Count + 1, 2)) + 1);
                nodeStack.Push(new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.ISROOT));

                while (currentNode != m_Bottom)
                {
                    parent           = currentNode;
                    comparisonResult = CompareTo(data, currentNode.Data, COMPARISON_TYPE.INSERT);
                    TraversalHistory histEntry;

                    // switch between left or right
                    if (comparisonResult <= 0)
                    {
                        currentNode = currentNode.Left;
                        histEntry   = new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.LEFT);
                        nodeStack.Push(histEntry);
                    }
                    else if (comparisonResult > 0)
                    {
                        currentNode = currentNode.Right;
                        histEntry   = new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.RIGHT);
                        nodeStack.Push(histEntry);
                    }
                }

                // check if traversed until bottom
                bool didInsert = false;
                if (nodeStack.Pop().node == m_Bottom) // This node must be m_Bottom.
                {
                    // use last comparison result and parent to insert new node
                    if (comparisonResult <= 0)
                    {
                        parent.Left = CreateNode(data);
                        didInsert   = true;
                    }
                    else if (comparisonResult > 0)
                    {
                        parent.Right = CreateNode(data);
                        didInsert    = true;
                    }
                }

                // pop history stack and change shift tree when necessary
                while (nodeStack.Count != 0)
                {
                    TraversalHistory t = nodeStack.Pop();
                    Node             n = t.node;
                    n = Skew(n, t.parentNode, t.side);
                    Split(n, t.parentNode, t.side);
                }

                // return whether a node was inserted
                return(didInsert);
            }
        }
示例#2
0
        public bool Delete(T data)
        {
            if (m_Root == m_Bottom /*|| EqualityComparer<T>.Default.Equals(data, default(T)) */)
            {
                return(false);
            }

            Node currentNode = m_Root;
            Node parent      = null;
            Node deleted     = m_Bottom;
            Stack <TraversalHistory> nodeStack = new Stack <TraversalHistory>((int)Math.Ceiling(Math.Log(Count + 1, 2)) + 1);

            nodeStack.Push(new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.ISROOT));
            while (currentNode != m_Bottom)
            {
                parent = currentNode;
                TraversalHistory hist;
                int comparisonResult = CompareTo(data, currentNode.Data, COMPARISON_TYPE.DELETE);
                if (comparisonResult < 0)
                {
                    currentNode = currentNode.Left;
                    hist        = new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.LEFT);
                }
                else
                {
                    deleted     = currentNode;
                    currentNode = currentNode.Right;
                    hist        = new TraversalHistory(currentNode, parent, TraversalHistory.ECHILDSIDE.RIGHT);
                }
                nodeStack.Push(hist);
            }

            bool didDelete = false;

            if (deleted != m_Bottom && CompareTo(data, deleted.Data, COMPARISON_TYPE.DELETE) == 0)
            {
                if (nodeStack.Pop().node != m_Bottom) // Pop since the last entry is m_Bottom
                {
                    throw new Exception("First node in traversal history was not Bottom!");
                }
                TraversalHistory lastHist = nodeStack.Pop();
                Node             last     = lastHist.node; // This is the node that is leftmost of the node that we want to delete.
                if (last.Left != m_Bottom)
                {
                    throw new Exception("Last has a left child that is not Bottom!");
                }
                deleted.Data = last.Data;
                Node copy = last.Right;
                if (copy != m_Bottom)
                {
                    last.Data  = copy.Data;
                    last.Left  = copy.Left;
                    last.Right = copy.Right;
                    last.Level = copy.Level;
                    // Destroy the node
                    copy.Left  = null;
                    copy.Right = null;
                    copy.Data  = default(T);
                }
                else
                {
                    if (lastHist.side == TraversalHistory.ECHILDSIDE.LEFT)
                    {
                        lastHist.parentNode.Left = m_Bottom;
                    }
                    else if (lastHist.side == TraversalHistory.ECHILDSIDE.RIGHT)
                    {
                        lastHist.parentNode.Right = m_Bottom;
                    }
                    else
                    {
                        m_Root = m_Bottom;
                    }
                }
                --Count;
                didDelete = true;
            }

            // pop history stack and change tree when necessary
            while (nodeStack.Count != 0)
            {
                TraversalHistory t = nodeStack.Pop();
                Node             n = t.node;
                if (n.Left.Level < n.Level - 1 || n.Right.Level < n.Level - 1)
                {
                    --n.Level;
                    if (n.Right.Level > n.Level)
                    {
                        n.Right.Level = n.Level;
                    }
                    n             = Skew(n, t.parentNode, t.side);
                    n.Right       = Skew(n.Right, n, TraversalHistory.ECHILDSIDE.RIGHT);
                    n.Right.Right = Skew(n.Right.Right, n.Right, TraversalHistory.ECHILDSIDE.RIGHT);
                    n             = Split(n, t.parentNode, t.side);
                    n.Right       = Split(n.Right, n, TraversalHistory.ECHILDSIDE.RIGHT);
                }
            }
            return(didDelete);
        }