Exemplo n.º 1
0
        /// <summary>Adds an item to the heap.</summary>
        /// <param name="key">The key for this entry.</param>
        /// <param name="value">The value for this entry.</param>
        public virtual void Insert(IComparable key, object value)
        {
            // Create the entry based on the provided key and value
            ChoBinaryHeapEntry entry = new ChoBinaryHeapEntry(key, value);

            // Add the item to the list, making sure to keep track of where it was added.
            int pos = _list.Add(entry); // don't actually need it inserted yet, but want to make sure there's enough space for it

            // If it was added at the beginning, i.e. this is the only item, we're done.
            if (pos == 0)
            {
                return;
            }

            // Otherwise, perform log(n) operations, walking up the tree, swapping
            // where necessary based on key values
            while (pos > 0)
            {
                // Get the next position to check
                int nextPos = pos / 2;

                // Extract the entry at the next position
                ChoBinaryHeapEntry toCheck = (ChoBinaryHeapEntry)_list[nextPos];

                // Compare that entry to our new one.  If our entry has a larger key, move it up.
                // Otherwise, we're done.
                if (entry.CompareTo(toCheck) > 0)
                {
                    _list[pos] = toCheck;
                    pos        = nextPos;
                }
                else
                {
                    break;
                }
            }

            // Make sure we put this entry back in, just in case
            _list[pos] = entry;
        }
Exemplo n.º 2
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);
        }