Exemplo n.º 1
0
        /// <summary>Removes the entry at the top of the heap.</summary>
        /// <returns>The removed entry.</returns>
        public virtual object Remove()
        {
            // Get the first item and save it for later (this is what will be returned).
            if (_list.Count == 0)
            {
                throw new InvalidOperationException("Cannot remove an item from the heap as it is empty.");
            }
            object toReturn = ((ChoBinaryHeapEntry)_list[0]).Value;

            // Remove the first item
            _list.RemoveAt(0);

            // See if we can stop now (if there's only one item or we're empty, we're done)
            if (_list.Count > 1)
            {
                // Move the last element to the beginning
                _list.Insert(0, _list[_list.Count - 1]);
                _list.RemoveAt(_list.Count - 1);

                // Start reheapify
                int current = 0, possibleSwap = 0;

                // Keep going until the tree is a heap
                while (true)
                {
                    // Get the positions of the node's children
                    int leftChildPos  = 2 * current + 1;
                    int rightChildPos = leftChildPos + 1;

                    // Should we swap with the left child?
                    if (leftChildPos < _list.Count)
                    {
                        // Get the two entries to compare (node and its left child)
                        ChoBinaryHeapEntry entry1 = (ChoBinaryHeapEntry)_list[current];
                        ChoBinaryHeapEntry entry2 = (ChoBinaryHeapEntry)_list[leftChildPos];

                        // If the child has a higher key than the parent, set that as a possible swap
                        if (entry2.CompareTo(entry1) > 0)
                        {
                            possibleSwap = leftChildPos;
                        }
                    }
                    else
                    {
                        break;  // if can't swap this, we're done
                    }
                    // Should we swap with the right child?  Note that now we check with the possible swap
                    // position (which might be current and might be left child).
                    if (rightChildPos < _list.Count)
                    {
                        // Get the two entries to compare (node and its left child)
                        ChoBinaryHeapEntry entry1 = (ChoBinaryHeapEntry)_list[possibleSwap];
                        ChoBinaryHeapEntry entry2 = (ChoBinaryHeapEntry)_list[rightChildPos];

                        // If the child has a higher key than the parent, set that as a possible swap
                        if (entry2.CompareTo(entry1) > 0)
                        {
                            possibleSwap = rightChildPos;
                        }
                    }

                    // Now swap current and possible swap if necessary
                    if (current != possibleSwap)
                    {
                        object temp = _list[current];
                        _list[current]      = _list[possibleSwap];
                        _list[possibleSwap] = temp;
                    }
                    else
                    {
                        break;  // if nothing to swap, we're done
                    }
                    // Update current to the location of the swap
                    current = possibleSwap;
                }
            }

            // Return the item from the heap
            return(toReturn);
        }