Skip to content

Commit 4ea8571

Browse files
committed
- optimization to bulk insert into heap as per @cristaloleg suggestion #32
1 parent 549b638 commit 4ea8571

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

README.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -710,9 +710,7 @@ func main() {
710710
return -utils.IntComparator(a, b)
711711
}
712712
heap = binaryheap.NewWith(inverseIntComparator) // empty (min-heap)
713-
heap.Push(2) // 2
714-
heap.Push(3) // 3, 2
715-
heap.Push(1) // 3, 2, 1
713+
heap.Push(2, 3, 1) // 3, 2, 1 (bulk optimized)
716714
heap.Values() // 3, 2, 1
717715
}
718716
```

trees/binaryheap/binaryheap.go

+22-6
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,20 @@ func NewWithStringComparator() *Heap {
4545
}
4646

4747
// Push adds a value onto the heap and bubbles it up accordingly.
48-
func (heap *Heap) Push(value interface{}) {
49-
heap.list.Add(value)
50-
heap.bubbleUp()
48+
func (heap *Heap) Push(values ...interface{}) {
49+
if len(values) == 1 {
50+
heap.list.Add(values[0])
51+
heap.bubbleUp()
52+
} else {
53+
// Reference: https://en.wikipedia.org/wiki/Binary_heap#Building_a_heap
54+
for _, value := range values {
55+
heap.list.Add(value)
56+
}
57+
size := heap.list.Size()/2 + 1
58+
for i := size; i >= 0; i-- {
59+
heap.bubbleDownIndex(i)
60+
}
61+
}
5162
}
5263

5364
// Pop removes top element on heap and returns it, or nil if heap is empty.
@@ -101,10 +112,15 @@ func (heap *Heap) String() string {
101112
return str
102113
}
103114

104-
// Performs the "bubble down" operation. This is to place the element that is at the
105-
// root of the heap in its correct place so that the heap maintains the min/max-heap order property.
115+
// Performs the "bubble down" operation. This is to place the element that is at the root
116+
// of the heap in its correct place so that the heap maintains the min/max-heap order property.
106117
func (heap *Heap) bubbleDown() {
107-
index := 0
118+
heap.bubbleDownIndex(0)
119+
}
120+
121+
// Performs the "bubble down" operation. This is to place the element that is at the index
122+
// of the heap in its correct place so that the heap maintains the min/max-heap order property.
123+
func (heap *Heap) bubbleDownIndex(index int) {
108124
size := heap.list.Size()
109125
for leftIndex := index<<1 + 1; leftIndex < size; leftIndex = index<<1 + 1 {
110126
rightIndex := index<<1 + 2

trees/binaryheap/binaryheap_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ func TestBinaryHeapPush(t *testing.T) {
3434
}
3535
}
3636

37+
func TestBinaryHeapPushBulk(t *testing.T) {
38+
heap := NewWithIntComparator()
39+
40+
heap.Push(15, 20, 3, 1, 2)
41+
42+
if actualValue := heap.Values(); actualValue[0].(int) != 1 || actualValue[1].(int) != 2 || actualValue[2].(int) != 3 {
43+
t.Errorf("Got %v expected %v", actualValue, "[1,2,3]")
44+
}
45+
if actualValue, ok := heap.Pop(); actualValue != 1 || !ok {
46+
t.Errorf("Got %v expected %v", actualValue, 1)
47+
}
48+
}
49+
3750
func TestBinaryHeapPop(t *testing.T) {
3851
heap := NewWithIntComparator()
3952

0 commit comments

Comments
 (0)