-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbinary_search_tree.rb
191 lines (150 loc) · 3.99 KB
/
binary_search_tree.rb
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
class Node
attr_accessor(:left, :value, :right)
def initialize(start_value = nil)
_create_node(self, start_value) unless start_value.nil?
end
def _node_exists?(node)
return node != nil && node.value != nil
end
def _create_node(node, value)
node.left = Node.new
node.right = Node.new
node.value = value
end
def _insert(node, value)
if !_node_exists?(node)
_create_node(node, value)
elsif value < node.value
_insert(node.left, value)
# elsif value >= node.value
else
_insert(node.right, value)
end
end
def insert(value)
_insert(self, value)
end
def insert_array(arr)
arr.each do |el|
insert(el)
end
end
def _search(node, value)
return if !_node_exists?(node)
return node if node.value == value
return _search(node.left, value) if value < node.value
return _search(node.right, value)
end
def search(value)
result =_search(self, value)
result.nil? ? result : result.value
end
def _min(node)
return if !_node_exists?(node)
return node if !_node_exists?(node.left)
return _min(node.left)
end
def min
_min(self).value
end
def _max(node)
return if !_node_exists?(node)
return node if !_node_exists?(node.right)
return _max(node.right)
end
def max
_max(self).value
end
# симметричный обход
def _in_order_traversal(node)
return if !_node_exists?(node)
_in_order_traversal(node.left)
print("#{node.value} ")
_in_order_traversal(node.right)
end
def in_order_traversal
_in_order_traversal(self)
end
def _in_order_traversal_to_array(node, arr)
return if !_node_exists?(node)
_in_order_traversal_to_array(node.left, arr)
arr << node.value
_in_order_traversal_to_array(node.right, arr)
end
def in_order_traversal_to_array
arr = []
_in_order_traversal_to_array(self, arr)
arr
end
# обратный обход
def _post_order_traversal(node)
return if !_node_exists?(node)
_post_order_traversal(node.left)
_post_order_traversal(node.right)
print("#{node.value} ")
end
def post_order_traversal
_post_order_traversal(self)
end
# прямой обход
def _pre_order_traversal(node)
return if !_node_exists?(node)
print("#{node.value} ")
_pre_order_traversal(node.left)
_pre_order_traversal(node.right)
end
def pre_order_traversal
_pre_order_traversal(self)
end
# замена одного узла другим узлом
def _transplant_node(to_node, from_node)
to_node.value = from_node.value
to_node.left = from_node.left
to_node.right = from_node.right
end
# получение количества детей у узла
def _children_count(node)
count = 0
count += 1 if _node_exists?(node.left)
count += 1 if _node_exists?(node.right)
return count
end
# получение ребенка
def _child_or_nil(node)
return _node_exists?(node.left) ? node.left : node.right
end
def _remove_node_with_one_or_zero_child(node_to_delete)
child_to_replace = _child_or_nil(node_to_delete)
_transplant_node(node_to_delete, child_to_replace)
end
def remove(value)
_remove(self, value)
end
def _remove(root, value)
node_to_delete = _search(root, value)
return false if !_node_exists?(node_to_delete)
if _children_count(node_to_delete) < 2
_remove_node_with_one_or_zero_child(node_to_delete)
else
min_node = _min(node_to_delete.right)
node_to_delete.value = min_node.value
_remove_node_with_one_or_zero_child(min_node)
end
return true
end
end
n1 = Node.new(9)
p n1.in_order_traversal_to_array # [9]
n1 = Node.new
n1.insert(6)
p n1.in_order_traversal_to_array # [6]
arr1 = [5,3,4,2,1]
n1.insert_array(arr1)
p n1.min # 1
p n1.max # 6
p n1.search(4) # 4
p n1.in_order_traversal_to_array # [1, 2, 3, 4, 5, 6]
p n1.remove(8) # false
p n1.remove(4) # true
p n1.in_order_traversal_to_array # [1, 2, 3, 5, 6]
p n1.search(4) # nil