UpdateValue ( TKey existingKey, TValue newValue ) { AssertValid(); const String MethodName = "UpdateValue"; Int32 iExistingItemIndex = GetExistingItemIndex(existingKey, MethodName); BinaryHeapItem <TKey, TValue> oExistingItem = m_oItems[iExistingItemIndex]; TValue oExistingValue = oExistingItem.Value; oExistingItem.Value = newValue; Int32 iComparison = m_oValueComparer.Compare(newValue, oExistingValue); if (iComparison > 0) { SiftUp(iExistingItemIndex); } else if (iComparison < 0) { SiftDown(iExistingItemIndex); } AssertValid(); }
TryGetLeftOrRightChild ( Int32 iItemIndex, Boolean bLeftChild, out BinaryHeapItem <TKey, TValue> oLeftOrRightChildItem, out Int32 iLeftOrRightChildIndex ) { Debug.Assert(iItemIndex >= 0); Debug.Assert(iItemIndex < m_oItems.Count); AssertValid(); iLeftOrRightChildIndex = 2 * iItemIndex + (bLeftChild ? 1 : 2); oLeftOrRightChildItem = null; if (iLeftOrRightChildIndex < m_oItems.Count) { oLeftOrRightChildItem = m_oItems[iLeftOrRightChildIndex]; return(true); } iLeftOrRightChildIndex = Int32.MinValue; return(false); }
Add ( TKey key, TValue value ) { AssertValid(); // Add an item at the bottom of the tree. BinaryHeapItem <TKey, TValue> oItem = new BinaryHeapItem <TKey, TValue>(key, value); m_oItems.Add(oItem); Int32 iItemIndex = m_oItems.Count - 1; m_oItemDictionary.Add(key, iItemIndex); // Sift up from the bottom. SiftUp(iItemIndex); AssertValid(); }
TryGetRightChild ( Int32 iItemIndex, out BinaryHeapItem <TKey, TValue> oRightChildItem, out Int32 iRightChildIndex ) { Debug.Assert(iItemIndex >= 0); Debug.Assert(iItemIndex < m_oItems.Count); AssertValid(); return(TryGetLeftOrRightChild(iItemIndex, false, out oRightChildItem, out iRightChildIndex)); }
Remove ( TKey key ) { AssertValid(); Int32 iRemovedItemIndex; if (!m_oItemDictionary.TryGetValue(key, out iRemovedItemIndex)) { // The item doesn't exist. return; } BinaryHeapItem <TKey, TValue> oRemovedItem = m_oItems[iRemovedItemIndex]; Int32 iItems = m_oItems.Count; Int32 iLastItemIndex = iItems - 1; BinaryHeapItem <TKey, TValue> oLastItem = m_oItems[iLastItemIndex]; // Swap the specified item with the last item. SwapItems(iRemovedItemIndex, iLastItemIndex); // Remove the last item and update the item dictionary. m_oItems.RemoveAt(iLastItemIndex); m_oItemDictionary.Remove(oRemovedItem.Key); if (iRemovedItemIndex != iLastItemIndex) { Int32 iComparison = m_oValueComparer.Compare(oLastItem.Value, oRemovedItem.Value); if (iComparison > 0) { SiftUp(iRemovedItemIndex); } else if (iComparison < 0) { SiftDown(iRemovedItemIndex); } } AssertValid(); }
RemoveTop() { AssertValid(); const String MethodName = "RemoveTop"; Int32 iItems = m_oItems.Count; if (iItems == 0) { Debug.Assert(false); throw new InvalidOperationException(String.Format( "{0}.{1}: The heap is empty.", this.ClassName, MethodName )); } BinaryHeapItem <TKey, TValue> oRemovedItem = m_oItems[0]; Int32 iLastItemIndex = iItems - 1; // Swap the first item with the last item. SwapItems(0, iLastItemIndex); // Remove the last item and update the item dictionary. m_oItems.RemoveAt(iLastItemIndex); m_oItemDictionary.Remove(oRemovedItem.Key); if (m_oItems.Count > 0) { // Sift down from the top. SiftDown(0); } AssertValid(); return(oRemovedItem); }
TryGetTop ( out BinaryHeapItem <TKey, TValue> top ) { AssertValid(); top = null; if (m_oItems.Count == 0) { return(false); } top = m_oItems[0]; return(true); }
SwapItems ( Int32 iItem1Index, Int32 iItem2Index ) { Debug.Assert(iItem1Index >= 0); Debug.Assert(iItem1Index < m_oItems.Count); Debug.Assert(iItem2Index >= 0); Debug.Assert(iItem2Index < m_oItems.Count); AssertValid(); BinaryHeapItem <TKey, TValue> oItem1 = m_oItems[iItem1Index]; BinaryHeapItem <TKey, TValue> oItem2 = m_oItems[iItem2Index]; m_oItems[iItem1Index] = oItem2; m_oItems[iItem2Index] = oItem1; m_oItemDictionary[oItem1.Key] = iItem2Index; m_oItemDictionary[oItem2.Key] = iItem1Index; }
SiftUp ( Int32 iItemIndex ) { Debug.Assert(iItemIndex >= 0); Debug.Assert(iItemIndex < m_oItems.Count); AssertValid(); if (iItemIndex == 0) { return; } BinaryHeapItem <TKey, TValue> oItem = m_oItems[iItemIndex]; Int32 iParentIndex; BinaryHeapItem <TKey, TValue> oParentItem; while (TryGetParent(iItemIndex, out oParentItem, out iParentIndex)) { // Compare the item with its parent. if (m_oValueComparer.Compare(oParentItem.Value, oItem.Value) >= 0) { // The heap property is satisfied. break; } // Swap the item with its parent. SwapItems(iItemIndex, iParentIndex); iItemIndex = iParentIndex; } }
TryGetParent ( Int32 iItemIndex, out BinaryHeapItem <TKey, TValue> oParentItem, out Int32 iParentIndex ) { Debug.Assert(iItemIndex >= 0); Debug.Assert(iItemIndex < m_oItems.Count); AssertValid(); iParentIndex = Int32.MinValue; oParentItem = null; if (iItemIndex == 0) { return(false); } iParentIndex = (iItemIndex - 1) / 2; oParentItem = m_oItems[iParentIndex]; return(true); }
SiftDown ( Int32 iItemIndex ) { Debug.Assert(iItemIndex >= 0); Debug.Assert(iItemIndex < m_oItems.Count); AssertValid(); BinaryHeapItem <TKey, TValue> oItem = m_oItems[iItemIndex]; while (true) { BinaryHeapItem <TKey, TValue> oLeftChildItem; Int32 iLeftChildIndex; if (!TryGetLeftChild(iItemIndex, out oLeftChildItem, out iLeftChildIndex)) { // We're at the bottom of the tree. break; } // Assume that we need to compare the parent to its left child. Int32 iChildItemIndexToCompareTo = iLeftChildIndex; BinaryHeapItem <TKey, TValue> oChildItemToCompareTo = oLeftChildItem; BinaryHeapItem <TKey, TValue> oRightChildItem; Int32 iRightChildIndex; if (TryGetRightChild(iItemIndex, out oRightChildItem, out iRightChildIndex)) { if (m_oValueComparer.Compare(oRightChildItem.Value, oLeftChildItem.Value) >= 0) { // We need to compare the parent to its right child. oChildItemToCompareTo = oRightChildItem; iChildItemIndexToCompareTo = iRightChildIndex; } } if (m_oValueComparer.Compare(oItem.Value, oChildItemToCompareTo.Value) >= 0) { // The heap property is satisfied. break; } // Swap the item with its left or right child. SwapItems(iItemIndex, iChildItemIndexToCompareTo); iItemIndex = iChildItemIndexToCompareTo; } }