forked from eileen-code4fun/LSM-Tree
-
Notifications
You must be signed in to change notification settings - Fork 0
/
binary_tree.go
110 lines (102 loc) · 2.48 KB
/
binary_tree.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package lsmt
import (
"fmt"
)
type TreeNode struct {
Elem Element
Left *TreeNode
Right *TreeNode
Size int
}
// NewTree accepts a sorted element slice and returns a binary tree representation.
func NewTree(elems []Element) *TreeNode {
size := len(elems)
if size == 0 {
return nil
}
root := &TreeNode{
Elem: elems[size/2],
Left: NewTree(elems[0:size/2]),
Size: size,
}
if rightIndex := size/2+1; rightIndex < size {
root.Right = NewTree(elems[rightIndex:size])
}
return root
}
func Upsert(tree **TreeNode, elem Element) {
if *tree == nil {
*tree = &TreeNode{Elem: elem, Size: 1}
} else if elem.Key < (*tree).Elem.Key {
Upsert(&((*tree).Left), elem)
(*tree).Size++
} else if elem.Key > (*tree).Elem.Key {
Upsert(&((*tree).Right), elem)
(*tree).Size++
} else {
(*tree).Elem.Value = elem.Value
}
}
func Find(tree *TreeNode, key string) (Element, error) {
if tree == nil {
// Not found.
return Element{}, fmt.Errorf("key %s not found", key)
} else if tree.Elem.Key == key {
return tree.Elem, nil
}
if key <= tree.Elem.Key {
return Find(tree.Left, key)
} else {
return Find(tree.Right, key)
}
}
// Traverse returns all the elements in key order.
func Traverse(tree *TreeNode) []Element {
var elems []Element
if tree == nil {
return elems
}
left := Traverse(tree.Left)
right := Traverse(tree.Right)
elems = append(elems, left...)
elems = append(elems, tree.Elem)
return append(elems, right...)
}
func JustSmallerOrEqual(tree *TreeNode, key string) (Element, error) {
if tree == nil {
return Element{}, fmt.Errorf("key %s is smaller than any key in the tree", key)
}
current := tree.Elem
if current.Key <= key {
right, err := JustSmallerOrEqual(tree.Right, key)
if err == nil && current.Key < right.Key {
current = right
}
} else {
left, err := JustSmallerOrEqual(tree.Left, key)
if err != nil {
return Element{}, err
}
current = left
}
return current, nil
}
func JustLarger(tree *TreeNode, key string) (Element, error) {
if tree == nil {
return Element{}, fmt.Errorf("key %s is larger than any key in the tree", key)
}
current := tree.Elem
if current.Key > key {
left, err := JustLarger(tree.Left, key)
if err == nil && current.Key > left.Key {
current = left
}
} else {
right, err := JustLarger(tree.Right, key)
if err != nil {
return Element{}, err
}
current = right
}
return current, nil
}