-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbst.go
155 lines (123 loc) · 3.69 KB
/
bst.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package datastructures
import "fmt"
type Node struct {
Value int
Left *Node
Right *Node
}
type BinarySearchTree struct {
Root *Node
}
func (bst *BinarySearchTree) insert(node *Node, value int) *Node {
if node == nil {
return &Node{Value: value}
}
if value < node.Value {
node.Left = bst.insert(node.Left, value)
} else {
node.Right = bst.insert(node.Right, value)
}
return node
}
func (bst *BinarySearchTree) Insert(value int) {
bst.Root = bst.insert(bst.Root, value)
}
func (bst *BinarySearchTree) search(node *Node, value int) bool {
if node == nil {
return false
}
if value == node.Value {
return true
}
if value < node.Value {
return bst.search(node.Left, value)
} else {
return bst.search(node.Right, value)
}
}
func (bst *BinarySearchTree) Search(value int) bool {
return bst.search(bst.Root, value)
}
// InOrderTraversal: At first traverse left subtree then visit the root and then traverse the right subtree.
func (bst *BinarySearchTree) traversal(node *Node) {
if node == nil {
return
}
bst.traversal(node.Left)
fmt.Printf("%d -> ", node.Value)
bst.traversal(node.Right)
}
func (bst *BinarySearchTree) Traversal() {
bst.traversal(bst.Root)
fmt.Println()
}
// PreOrderTraversal: At first visit the root then traverse the left subtree and then traverse the right subtree.
func (bst *BinarySearchTree) preOrderTraversal(node *Node) {
if node == nil {
return
}
fmt.Printf("%d -> ", node.Value)
bst.preOrderTraversal(node.Left)
bst.preOrderTraversal(node.Right)
}
func (bst *BinarySearchTree) PreOrderTraversal() {
bst.preOrderTraversal(bst.Root)
fmt.Println()
}
// PostOrderTraversal: At first traverse left subtree then traverse the right subtree and then visit the root.
func (bst *BinarySearchTree) postOrderTraversal(node *Node) {
if node == nil {
return
}
bst.postOrderTraversal(node.Left)
bst.postOrderTraversal(node.Right)
fmt.Printf("%d -> ", node.Value)
}
func (bst *BinarySearchTree) PostOrderTraversal() {
bst.postOrderTraversal(bst.Root)
fmt.Println()
}
// InOrderSuccessor: The in-order successor of a node is the next node in the in-order traversal of the tree.
// The in-order successor of a node is the leftmost node in the right subtree of the node.
// 🔥 Replacing the node with its in-order successor will not change the in-order traversal of the tree since there are no nodes between the node and its in-order successor.
func (bst *BinarySearchTree) inOrderSuccessor(node *Node) *Node {
current := node.Right
for current.Left != nil {
current = current.Left
}
return current
}
func (bst *BinarySearchTree) delete(node *Node, value int) *Node {
// If the tree is empty
if node == nil {
return node
}
// If the value to be deleted is less than the root value, then it lies in the left subtree
if value < node.Value {
node.Left = bst.delete(node.Left, value)
}
// If the value to be deleted is greater than the root value, then it lies in the right subtree
if value > node.Value {
node.Right = bst.delete(node.Right, value)
}
// If the value to be deleted is equal to the root value, then this is the node to be deleted
if value == node.Value {
// If the node has only one child or no child
if node.Left == nil {
return node.Right
}
if node.Right == nil {
return node.Left
}
// If the node has two children, then get the in-order successor (smallest in the right subtree)
inOrderSuccessor := bst.inOrderSuccessor(node)
// Copy the in-order successor value to the node
node.Value = inOrderSuccessor.Value
// Delete the in-order successor
node.Right = bst.delete(node.Right, inOrderSuccessor.Value)
}
return node
}
func (bst *BinarySearchTree) Delete(value int) {
bst.Root = bst.delete(bst.Root, value)
}