Skip to content

Commit d58ef92

Browse files
author
Theo
committed
Refactored Leftist heap
1 parent e3bfd4d commit d58ef92

File tree

4 files changed

+45
-24
lines changed

4 files changed

+45
-24
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ $ go get -u github.com/theodesp/go-heaps
2929
**Heaps**
3030

3131
* [Pairing Heap](https://en.wikipedia.org/wiki/Pairing_heap): A pairing heap is a type of heap data structure with relatively simple implementation and excellent practical amortized performance.
32-
* [Leftlist Heap](https://www.geeksforgeeks.org/leftist-tree-leftist-heap/): a variant of a binary heap. Every node has an s-value which is the distance to the nearest leaf. In contrast to a binary heap, a leftist tree attempts to be very unbalanced.
32+
* [Leftist Heap](https://www.geeksforgeeks.org/leftist-tree-leftist-heap/): a variant of a binary heap. Every node has an s-value which is the distance to the nearest leaf. In contrast to a binary heap, a leftist tree attempts to be very unbalanced.
3333
* [Skew Heap](https://en.wikipedia.org/wiki/Skew_heap): A skew heap (or self-adjusting heap) is a heap data structure implemented as a binary tree. Skew heaps are advantageous because of their ability to merge more quickly than binary heaps.
3434
* [Fibonacci Heap](https://en.wikipedia.org/wiki/Fibonacci_heap): a Fibonacci heap is a data structure for priority queue operations, consisting of a collection of heap-ordered trees. It has a better amortized running time than many other priority queue data structures including the binary heap and binomial heap.
3535
* [Binomial Heap](https://www.geeksforgeeks.org/binomial-heap-2/): A Binomial Heap is a collection of Binomial Trees. A Binomial Heap is a set of Binomial Trees where each Binomial Tree follows Min Heap property. And there can be at most one Binomial Tree of any degree.
@@ -62,7 +62,7 @@ func main() {
6262
```
6363

6464
## Complexity
65-
| Operation | Pairing | Leftlist | Skew | Fibonacci | Binomial | Treap |
65+
| Operation | Pairing | Leftist | Skew | Fibonacci | Binomial | Treap |
6666
| ------------- |:-------------:|:-------------:|:-------------:|:-------------:|:-------------:|:-------------:|
6767
| FindMin | Θ(1) | Θ(1) | Θ(1) | Θ(1) | Θ(log n) | O(n) |
6868
| DeleteMin | O(log n) | O(log n) | O(log n) | O(log n) | Θ(log n) | O(n) |

example/leftlist/leftlist.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
)
88

99
func main() {
10-
heap := leftlist.New()
10+
heap := leftist.New()
1111
heap.Insert(Int(4))
1212
heap.Insert(Int(19))
1313
heap.Insert(Int(8))
Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
package leftlist
1+
package leftist
22

33
import (
44
heap "github.com/theodesp/go-heaps"
55
)
66

77
// Node is a leaf in the heap.
88
type Node struct {
9-
Item heap.Item
10-
Left, Right *Node
9+
item heap.Item
10+
left, right *Node
1111
s int // s-value (or rank)
1212
}
1313

1414
// LeftistHeap is a leftist heap implementation.
1515
type LeftistHeap struct {
16-
Root *Node
16+
root *Node
1717
}
1818

1919
func mergeNodes(x, y *Node) *Node {
@@ -25,35 +25,37 @@ func mergeNodes(x, y *Node) *Node {
2525
return x
2626
}
2727
// Compare the roots of two heaps.
28-
if x.Item.Compare(y.Item) == 1 {
28+
if x.item.Compare(y.item) > 0 {
2929
return merge(y, x)
3030
} else {
3131
return merge(x, y)
3232
}
3333
}
3434

3535
func merge(x, y *Node) *Node {
36-
if x.Left == nil {
36+
if x.left == nil {
3737
// left child doesn't exist, so move right child to the smallest key
38-
x.Left = y
39-
x.Right = nil
38+
// to maintain the leftList invariant
39+
x.left = y
40+
x.right = nil
4041
} else {
41-
x.Right = mergeNodes(x.Right, y)
42+
x.right = mergeNodes(x.right, y)
4243
// left child does exist, so compare s-values
43-
if x.Left.s < x.Right.s {
44-
x.Left, x.Right = x.Right, x.Left
44+
if x.left.s < x.right.s {
45+
x.left, x.right = x.right, x.left
4546
}
4647
// since we know the right child has the lower s-value, we can just
4748
// add one to its s-value
48-
x.s = x.Right.s + 1
49+
x.s = x.right.s + 1
4950
}
5051

5152
return x
5253
}
5354

5455
// Init initializes or clears the LeftistHeap
5556
func (h *LeftistHeap) Init() *LeftistHeap {
56-
return &LeftistHeap{}
57+
h.root = &Node{}
58+
return h
5759
}
5860

5961
// New returns an initialized LeftistHeap.
@@ -62,30 +64,30 @@ func New() *LeftistHeap { return new(LeftistHeap).Init() }
6264
// Insert adds an item into the heap.
6365
// The complexity is O(log n) amortized.
6466
func (h *LeftistHeap) Insert(item heap.Item) heap.Item {
65-
h.Root = mergeNodes(&Node{
66-
Item: item,
67-
}, h.Root)
67+
h.root = mergeNodes(&Node{
68+
item: item,
69+
}, h.root)
6870

6971
return item
7072
}
7173

7274
// DeleteMin deletes the minimum value and returns it.
7375
// The complexity is O(log n) amortized.
7476
func (h *LeftistHeap) DeleteMin() heap.Item {
75-
item := h.Root.Item
77+
item := h.root.item
7678

77-
h.Root = mergeNodes(h.Root.Left, h.Root.Right)
79+
h.root = mergeNodes(h.root.left, h.root.right)
7880

7981
return item
8082
}
8183

8284
// FindMin finds the minimum value.
8385
// The complexity is O(1).
8486
func (h *LeftistHeap) FindMin() heap.Item {
85-
return h.Root.Item
87+
return h.root.item
8688
}
8789

8890
// Clear removes all items from the heap.
8991
func (h *LeftistHeap) Clear() {
90-
h.Root = nil
92+
h.Init()
9193
}

leftlist/leftist_heap_test.go renamed to leftist/leftist_heap_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package leftlist
1+
package leftist
22

33
import (
44
"sort"
@@ -43,6 +43,25 @@ func TestLeftistHeapString(t *testing.T) {
4343
}
4444
}
4545

46+
func TestLeftistHeap(t *testing.T) {
47+
heap := &LeftistHeap{}
48+
49+
numbers := []int{4, 3, -1, 5, 9}
50+
51+
for _, number := range numbers {
52+
heap.Insert(Int(number))
53+
}
54+
55+
if heap.FindMin() != Int(-1) {
56+
t.Fail()
57+
}
58+
59+
heap.Clear()
60+
if heap.FindMin() != nil {
61+
t.Fail()
62+
}
63+
}
64+
4665
func Int(value int) go_heaps.Integer {
4766
return go_heaps.Integer(value)
4867
}

0 commit comments

Comments
 (0)