Skip to content

Commit 2acc5b6

Browse files
committed
Introduce generics
The core data structure use generics instead of a type that satisfies the `item` interface.
1 parent 81d66d3 commit 2acc5b6

File tree

7 files changed

+159
-272
lines changed

7 files changed

+159
-272
lines changed

bstree.go

Lines changed: 53 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,33 @@
11
package bstree
22

33
import (
4+
"errors"
45
"fmt"
6+
7+
"golang.org/x/exp/constraints"
58
)
69

710
// BSTree represents a binary tree
8-
type BSTree struct {
9-
Root *Node
10-
}
11-
12-
// New returns a pointer to a new binary tree
13-
func New() *BSTree {
14-
return &BSTree{}
11+
type BSTree[K constraints.Ordered, V any] struct {
12+
Root *Node[K, V]
1513
}
1614

1715
// IsEmpty checks if the BSTree is empty
18-
func (tree *BSTree) IsEmpty() bool {
16+
func (tree *BSTree[K, V]) IsEmpty() bool {
1917
return tree.Root == nil
2018
}
2119

2220
// Size returns the size of the tree
23-
func (tree *BSTree) Size() int {
21+
func (tree *BSTree[K, V]) Size() int {
2422
return tree.Root.Size()
2523
}
2624

2725
// Height returns the height of the tree
28-
func (tree *BSTree) Height() int {
26+
func (tree *BSTree[K, V]) Height() int {
2927
return height(tree.Root)
3028
}
3129

32-
func height(node *Node) int {
30+
func height[K constraints.Ordered, V any](node *Node[K, V]) int {
3331
if node == nil {
3432
return 0
3533
}
@@ -47,76 +45,77 @@ func height(node *Node) int {
4745
}
4846

4947
// Put the item to the node
50-
func (tree *BSTree) Put(item Item) {
51-
tree.Root = put(tree.Root, item)
48+
func (tree *BSTree[K, V]) Put(key K, val V) {
49+
tree.Root = put(tree.Root, key, val)
50+
5251
}
5352

54-
func put(node *Node, item Item) *Node {
53+
func put[K constraints.Ordered, V any](node *Node[K, V], key K, val V) *Node[K, V] {
5554
if node == nil {
56-
return &Node{item: item, size: 1}
55+
return &Node[K, V]{key: key, value: val, size: 1}
5756
}
5857

59-
if item.LessThan(node.item) {
60-
node.left = put(node.left, item)
61-
} else if item.MoreThan(node.item) {
62-
node.right = put(node.right, item)
58+
if key < node.key {
59+
node.left = put(node.left, key, val)
60+
} else if key > node.key {
61+
node.right = put(node.right, key, val)
6362
} else {
64-
node.item = item
63+
node.value = val
6564
}
6665

6766
node.size = 1 + node.left.Size() + node.right.Size()
6867
return node
6968
}
7069

7170
// Find search for an item in the tree
72-
func (tree *BSTree) Find(item Item) (Item, bool) {
73-
return find(tree.Root, item)
71+
func (tree *BSTree[K, V]) Get(key K) (V, bool) {
72+
return get(tree.Root, key)
7473
}
7574

76-
func find(node *Node, item Item) (Item, bool) {
75+
func get[K constraints.Ordered, V any](node *Node[K, V], key K) (V, bool) {
7776
if node == nil {
78-
return nil, false
77+
return *new(V), false
7978
}
8079

81-
if item.LessThan(node.item) {
82-
return find(node.left, item)
83-
} else if item.MoreThan(node.item) {
84-
return find(node.right, item)
80+
if key < node.key {
81+
return get(node.left, key)
82+
} else if key > node.key {
83+
return get(node.right, key)
8584
} else {
86-
return node.item, true
85+
return node.value, true
8786
}
8887
}
8988

90-
// Min returns the min item of the tree
91-
func (tree *BSTree) Min() (Item, bool) {
89+
// Min returns the smallest key in the table
90+
func (tree *BSTree[K, V]) Min() (K, error) {
9291
if tree.IsEmpty() {
93-
return nil, false
92+
return *new(K), errors.New("calls min() on empty tree")
9493
}
9594

96-
node, found := min(tree.Root)
95+
node := min(tree.Root)
9796

98-
return node.item, found
97+
return node.key, nil
9998
}
10099

101-
func min(node *Node) (*Node, bool) {
100+
func min[K constraints.Ordered, V any](node *Node[K, V]) *Node[K, V] {
102101
if (node.left) == nil {
103-
return node, true
102+
return node
104103
}
105104

106105
return min(node.left)
107106
}
108107

109-
// DeleteMin deletes the min item of the tree
110-
func (tree *BSTree) DeleteMin() bool {
108+
// DeleteMin deletes the smallest key and associated value from the table.
109+
func (tree *BSTree[K, V]) DeleteMin() error {
111110
if tree.IsEmpty() {
112-
return false
111+
return errors.New("Symbol table is empty")
113112
}
114113

115114
tree.Root = deleteMin(tree.Root)
116-
return true
115+
return nil
117116
}
118117

119-
func deleteMin(node *Node) *Node {
118+
func deleteMin[K constraints.Ordered, V any](node *Node[K, V]) *Node[K, V] {
120119
if node.left == nil {
121120
return node.right
122121
}
@@ -127,20 +126,20 @@ func deleteMin(node *Node) *Node {
127126
return node
128127
}
129128

130-
// Delete an item from the tree
131-
func (tree *BSTree) Delete(item Item) {
132-
tree.Root = delete(tree.Root, item)
129+
// Removes the specified key and its associated value from this symbol table
130+
func (tree *BSTree[K, V]) Delete(key K) {
131+
tree.Root = delete(tree.Root, key)
133132
}
134133

135-
func delete(node *Node, item Item) *Node {
134+
func delete[K constraints.Ordered, V any](node *Node[K, V], key K) *Node[K, V] {
136135
if node == nil {
137136
return nil
138137
}
139138

140-
if item.LessThan(node.item) {
141-
node.left = delete(node.left, item)
142-
} else if item.MoreThan(node.item) {
143-
node.right = delete(node.right, item)
139+
if key < node.key {
140+
node.left = delete(node.left, key)
141+
} else if key > node.key {
142+
node.right = delete(node.right, key)
144143
} else {
145144

146145
if node.right == nil {
@@ -152,7 +151,7 @@ func delete(node *Node, item Item) *Node {
152151
}
153152

154153
t := node
155-
node, _ = min(t.right)
154+
node = min(t.right)
156155
node.right = deleteMin(t.right)
157156
node.left = t.left
158157
}
@@ -163,18 +162,18 @@ func delete(node *Node, item Item) *Node {
163162
}
164163

165164
// InOrderPrint traversal of the tree
166-
func (tree *BSTree) InOrderPrint() {
165+
func (tree *BSTree[K, V]) InOrderPrint() {
167166
inOrder(tree.Root)
168167
}
169168

170-
func inOrder(node *Node) {
169+
func inOrder[K constraints.Ordered, V any](node *Node[K, V]) {
171170
if node != nil {
172171
inOrder(node.left)
173-
fmt.Printf("%v ", node.item)
172+
fmt.Printf("%v ", node.value)
174173
inOrder(node.right)
175174
}
176175
}
177176

178-
func (tree *BSTree) String() string {
177+
func (tree *BSTree[K, V]) String() string {
179178
return fmt.Sprintf("%v", tree.Root)
180179
}

0 commit comments

Comments
 (0)