diff --git a/binomial/binomial_heap.go b/binomial/binomial_heap.go index 533bdff..5a4ed81 100644 --- a/binomial/binomial_heap.go +++ b/binomial/binomial_heap.go @@ -6,6 +6,8 @@ package binomial import ( + "math" + heap "github.com/theodesp/go-heaps" ) @@ -56,6 +58,53 @@ func (b *BinomialHeap) DeleteMin() heap.Item { return min.item } +// Deletes passed item from the heap. +// The complexity is O(log n). +func (p *BinomialHeap) Delete(item heap.Item) { + found := p.findAny(item) + next := found + for next.parent != nil { + temp := next.item + next.item = next.parent.item + next.parent.item = temp + + next = next.parent + } + next.item = heap.Integer(math.Inf(-1)) + p.DeleteMin() +} + +// FindAny returns the address of item in the heap. +func (b *BinomialHeap) findAny(item heap.Item) *node { + next := b.root + backToParent := false + + for next != nil { + if next.child != nil && !backToParent { + if next.item == item { + return next + } + next = next.child + backToParent = false + } else if next.sibling != nil { + if next.item == item { + return next + } + next = next.sibling + backToParent = false + } else if next.parent != nil { + if next.item == item { + return next + } + next = next.parent + backToParent = true + } else { + next = nil + } + } + return b.root +} + // FindMin returns the smallest item in the heap. // The complexity is O(log n). func (b *BinomialHeap) FindMin() heap.Item { diff --git a/binomial/binomial_heap_test.go b/binomial/binomial_heap_test.go index 518f8c2..f9c6b52 100644 --- a/binomial/binomial_heap_test.go +++ b/binomial/binomial_heap_test.go @@ -25,6 +25,50 @@ func TestLeftistHeapInteger(t *testing.T) { } } +func TestBinomialHeapIntegerDelete(t *testing.T) { + heap := &BinomialHeap{} + + numbers := []int{14, 112, 15, 16 , 71, 91, 1, 12, 23, 56, 34} + + for _, number := range numbers { + heap.Insert(Int(number)) + } + + heap.Delete(Int(15)) + heap.Delete(Int(12)) + + numbers = RemoveInts(numbers, 15) + numbers = RemoveInts(numbers, 12) + sort.Ints(numbers) + + for _, number := range numbers { + if Int(number) != heap.DeleteMin().(go_heaps.Integer) { + t.Fail() + } + } +} + +func TestBinomialHeapStringDelete(t *testing.T) { + heap := &BinomialHeap{} + + strings := []string{"a", "ccc", "bb", "d"} + + for _, str := range strings { + heap.Insert(Str(str)) + } + + heap.Delete(Str("ccc")) + + strings = RemoveStrs(strings, "ccc") + sort.Strings(strings) + + for _, str := range strings { + if Str(str) != heap.DeleteMin().(go_heaps.String) { + t.Fail() + } + } +} + func TestLeftistHeapString(t *testing.T) { heap := &BinomialHeap{} @@ -43,6 +87,20 @@ func TestLeftistHeapString(t *testing.T) { } } +func RemoveInts(s []int, hay int) []int { + sort.Ints(s) + i := sort.SearchInts(s, hay) + s[i] = s[len(s)-1] + return s[:len(s)-1] +} + +func RemoveStrs(s []string, hay string) []string { + sort.Strings(s) + i := sort.SearchStrings(s, hay) + s[i] = s[len(s)-1] + return s[:len(s)-1] +} + func Int(value int) go_heaps.Integer { return go_heaps.Integer(value) }