public void Add(IBinaryHeapItem item) { if (this.queue.Count == 0) { if (this.heap.Count == 0) { this.heap.Add(item); // It's very cheap. } else { int compareRes = item.CompareTo(this.heap.Peek()); if (compareRes != -1) // Even if equal, respect the stable order, don't "cut the line". { this.heap.Add(item); } else { this.queue.Enqueue(item); this.quickInsertionCount++; } } } else { int compareRes = item.CompareTo(this.queue.Peek()); if (compareRes == 1) // item is larger than the queue { this.heap.Add(item); } else // { if (compareRes == -1) // Item is smaller than the queue { while (this.queue.Count != 0) { IBinaryHeapItem fromQueue = this.queue.Dequeue(); this.heap.Add(fromQueue); this.quickInsertionCount--; this.quickInsertionsCancelled++; } } this.queue.Enqueue(item); this.quickInsertionCount++; } } //// The last removed item is the parent of all items added until another item is removed, //// or the same node that was last removed, partially expanded or deferred with increased cost. //// Otherwise the inserted item is one that was already in the open list, and its cost was //// was increased by one of the children of the last removed item. In this case, since the item //// wasn't the min of the open list and the last removed item was, now, with its increased cost, //// it certainly won't be smaller than the last removed item. //// If a partially expanded or otherwise deferred node is re-inserted with an updated cost, //// that must be done after all its children generated so far are inserted. Otherwise the //// cost comparison with the last removed item, which would still be the same node, would have //// incorrect results. }
private void DownHeap() //helper function that performs down-heap bubbling - bubbles the root down to its correct place // This is down if you imagine the heap as a down-growing tree: // 0 // 1 2 // 3 4 5 6 { _sorted = false; int n; int p = 0; IBinaryHeapItem item = _data[p]; while (true) { int ch1 = Child1(p); if (ch1 >= _count) { break; } int ch2 = Child2(p); if (ch2 >= _count) { n = ch1; } else { n = _data[ch1].CompareTo(_data[ch2]) < 0 ? ch1 : ch2; } if (item.CompareTo(_data[n]) > 0) { _data[p] = _data[n]; // Swap child up _data[p].SetIndexInHeap(p); p = n; } else { break; } } _data[p] = item; // Finally, place item at the base of the bubble-down chain _data[p].SetIndexInHeap(p); }
private void UpHeap() //helper function that performs up-heap bubbling - bubbles the last item up to its correct place // This is up if you imagine the heap as a down-growing tree: // 0 // 1 2 // 3 4 5 6 { _sorted = false; int p = _count - 1; IBinaryHeapItem item = _data[p]; int par = Parent(p); while (par > -1 && item.CompareTo(_data[par]) < 0) { _data[p] = _data[par]; // Swap parent down _data[p].SetIndexInHeap(p); p = par; par = Parent(p); } _data[p] = item; // Finally, place item at the base of the bubble-up chain _data[p].SetIndexInHeap(p); }