Example #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
			BinaryHeapEntry entry = new BinaryHeapEntry(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
				BinaryHeapEntry toCheck = (BinaryHeapEntry)_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;
		}
Example #2
0
    public BinaryHeap(int maxEntries)
    {
        m_heapEntries = new BinaryHeapEntry <T> [maxEntries * 2];

        for (int i = 0; i < m_heapEntries.Length; i++)
        {
            m_heapEntries[i].m_metricValue = float.PositiveInfinity;
        }
    }
Example #3
0
            /// <summary>Compares the current instance with another object of the same type.</summary>
            /// <param name="entry">An object to compare with this instance.</param>
            /// <returns>
            /// Less than 0 if this instance is less than the argument,
            /// 0 if the instances are equal,
            /// Greater than 0 if this instance is greater than the argument.
            /// </returns>
            public int CompareTo(BinaryHeapEntry entry)
            {
                // Make sure we have valid arguments.
                if (entry == null)
                {
                    throw new ArgumentNullException("entry", "Cannot compare to a null value.");
                }

                // Compare the keys
                return(_key.CompareTo(entry.Key));
            }
Example #4
0
    public T RemoveTop()
    {
        T top = m_heapEntries[0].m_object;

        if (m_maxIndex == 1)
        {
            m_heapEntries[0].m_metricValue = float.PositiveInfinity;
            m_maxIndex--;
            return(top);
        }

        // Chuck the lowest head entry at the top
        m_heapEntries[0] = m_heapEntries[m_maxIndex - 1];

        // Mark the final entry with #inf just for safety
        m_heapEntries[m_maxIndex - 1].m_metricValue = float.PositiveInfinity;

        // Lower the count
        m_maxIndex--;

        float currentCost = m_heapEntries[0].m_metricValue;

        int currentIndex = 0;

        bool lowestFound = false;

        while (!lowestFound)
        {
            int index1 = (currentIndex + 1) * 2;
            int index2 = ((currentIndex + 1) * 2) - 1;

            float cost1 = m_heapEntries[index1].m_metricValue;
            float cost2 = m_heapEntries[index2].m_metricValue;

            // If the current value is less than both children, it's reached the correct position, so stop
            if (currentCost < cost1 && currentCost < cost2)
            {
                lowestFound = true;
                break;
            }

            // Select the smaller child and swap the two
            int switchIndex = cost1 < cost2 ? index1 : index2;

            BinaryHeapEntry <T> tmp = m_heapEntries[switchIndex];
            m_heapEntries[switchIndex]  = m_heapEntries[currentIndex];
            m_heapEntries[currentIndex] = tmp;

            currentIndex = switchIndex;
        }

        return(top);
    }
Example #5
0
    public void Insert(T entry, float metricValue)
    {
        m_heapEntries[m_maxIndex].m_object      = entry;
        m_heapEntries[m_maxIndex].m_metricValue = metricValue;
        m_maxIndex++;

        for (int pos = m_maxIndex - 1; pos > 0 && metricValue < m_heapEntries[(pos - 1) / 2].m_metricValue; pos = (pos - 1) / 2)
        {
            BinaryHeapEntry <T> tmp = m_heapEntries[(pos - 1) / 2];
            m_heapEntries[(pos - 1) / 2] = m_heapEntries[pos];
            m_heapEntries[pos]           = tmp;
        }
    }
Example #6
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
            BinaryHeapEntry entry = new BinaryHeapEntry(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
                BinaryHeapEntry toCheck = (BinaryHeapEntry)_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;
        }
Example #7
0
            /// <summary>Compares the current instance with another object of the same type.</summary>
            /// <param name="entry">An object to compare with this instance.</param>
            /// <returns>
            /// Less than 0 if this instance is less than the argument,
            /// 0 if the instances are equal,
            /// Greater than 0 if this instance is greater than the argument.
            /// </returns>
            public int CompareTo(BinaryHeapEntry entry)
            {
                // Make sure we have valid arguments.
                if (entry == null) throw new ArgumentNullException("entry", "Cannot compare to a null value.");

                // Compare the keys
                return _key.CompareTo(entry.Key);
            }
Example #8
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 = ((BinaryHeapEntry)_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)
                        BinaryHeapEntry entry1 = (BinaryHeapEntry)_list[current];
                        BinaryHeapEntry entry2 = (BinaryHeapEntry)_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)
                        BinaryHeapEntry entry1 = (BinaryHeapEntry)_list[possibleSwap];
                        BinaryHeapEntry entry2 = (BinaryHeapEntry)_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);
        }