/// <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; }
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; } }
/// <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)); }
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); }
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; } }
/// <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; }
/// <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); }
/// <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); }