/************************************************************************************************/ /** PRIVATE HELPER FUNCTIONS */ /// <summary> /// Removes root of tree at he specified index. /// </summary> private void _removeAtIndex(int minIndex) { // Get the deletedTree // The min-root lies at _forest[minIndex] BinomialNode <T> deletedTreeRoot = _forest[minIndex].Child; // Exit if there was no children under old-min-root if (deletedTreeRoot == null) { return; } // CONSTRUCT H'' (double-prime) BinomialMinHeap <T> deletedForest = new BinomialMinHeap <T>(); deletedForest._forest.Resize(minIndex + 1); deletedForest._size = (1 << minIndex) - 1; for (int i = (minIndex - 1); i >= 0; --i) { deletedForest._forest[i] = deletedTreeRoot; deletedTreeRoot = deletedTreeRoot.Sibling; deletedForest._forest[i].Sibling = null; } // CONSTRUCT H' (single-prime) _forest[minIndex] = null; _size = deletedForest._size + 1; Merge(deletedForest); // Decrease the size --_size; }
/// <summary> /// Inserts a new item to heap. /// </summary> public void Add(T heapKey) { var tempHeap = new BinomialMinHeap <T>(); tempHeap._forest.Add(new BinomialNode <T>(heapKey)); tempHeap._size = 1; // Merge this with tempHeap Merge(tempHeap); // Increase the _size ++_size; }
/// <summary> /// Merges the elements of another heap with this heap. /// </summary> public void Merge(BinomialMinHeap <T> otherHeap) { // Avoid aliasing problems if (this == otherHeap) { return; } // Avoid null or empty cases if (otherHeap == null || otherHeap.IsEmpty()) { return; } BinomialNode <T> carryNode = null; _size = _size + otherHeap._size; // One capacity-change step if (_size > _forest.Count) { int newSize = Math.Max(this._forest.Count, otherHeap._forest.Count) + 1; this._forest.Resize(newSize); } for (int i = 0, j = 1; j <= _size; i++, j *= 2) { BinomialNode <T> treeRoot1 = (_forest.IsEmpty == true ? null : _forest[i]); BinomialNode <T> treeRoot2 = (i < otherHeap._forest.Count ? otherHeap._forest[i] : null); int whichCase = (treeRoot1 == null ? 0 : 1); whichCase += (treeRoot2 == null ? 0 : 2); whichCase += (carryNode == null ? 0 : 4); switch (whichCase) { /*** SINGLE CASES ***/ case 0: /* No trees */ case 1: /* Only this */ break; case 2: /* Only otherHeap */ this._forest[i] = treeRoot2; otherHeap._forest[i] = null; break; case 4: /* Only carryNode */ this._forest[i] = carryNode; carryNode = null; break; /*** BINARY CASES ***/ case 3: /* this and otherHeap */ carryNode = _combineTrees(treeRoot1, treeRoot2); this._forest[i] = otherHeap._forest[i] = null; break; case 5: /* this and carryNode */ carryNode = _combineTrees(treeRoot1, carryNode); this._forest[i] = null; break; case 6: /* otherHeap and carryNode */ carryNode = _combineTrees(treeRoot2, carryNode); otherHeap._forest[i] = null; break; case 7: /* all the nodes */ this._forest[i] = carryNode; carryNode = _combineTrees(treeRoot1, treeRoot2); otherHeap._forest[i] = null; break; } //end-switch } //end-for // Clear otherHeap otherHeap.Clear(); }