Binary Search Tree(BST) 는 탐색을 위한 자료구조로, 이진트리 형태를 가지되 몇가지 특징을 가지고 있다. 이 특징들은 노드들의 위치를 정의한다.
삽입 / 삭제 / 검색 의 구현
결과>
1) 모든 원소는 서로 다른 유일한 키를 갖는다
2) 왼쪽 서브 트리에 있는 원소의 키는 그 루트의 키보다 작다
3) 오른쪽 서브 트리에 있는 원소의 키는 그 루트의 키보다 크다
4) 왼쪽 서브 트리와 오른쪽 서브 트리도 이진 탐색 트리다
삽입 / 삭제 / 검색 의 구현
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
# Binary-Search-Tree Implementation
# Jungtaek Lim(Heart), 2009-03-04
class BinarySearchTreeNode
attr_accessor :left_child, :right_child, :key, :value
def initialize
@left_child = nil
@right_child = nil
@key = nil
@value = nil
end
end
class BinarySearchTree
def initialize
@root = nil
end
def insert_node(key, value)
node = BinarySearchTreeNode.new
node.key = key
node.value = value
if nil == @root
@root = node
return node
else
parent_node = find_place_for_insert(@root, key)
return nil if nil == parent_node
if parent_node.key > key
parent_node.left_child = node
else
parent_node.right_child = node
end
return node
end
end
def delete_node(key)
delete_node(@root, key)
end
def delete_node(root_node, key)
node = find_node(root_node, key)
return nil if nil == node
parent_node = find_parent_node(root_node, node.key)
degree = 0
degree += 1 unless nil == node.left_child
degree += 1 unless nil == node.right_child
case degree
when 0
if nil == parent_node # @root == node
@root = nil
return
end
if parent_node.left_child == node
parent_node.left_child = nil
else
parent_node.right_child = nil
end
when 1
if nil == parent_node # @root == node
if nil != node.left_child
@root = node.left_child
else
@root = node.right_child
end
return
end
child_node = (nil != node.left_child ? node.left_child : node.right_child)
if parent_node.left_child == node
parent_node.left_child = child_node
else
parent_node.right_child = child_node
end
when 2
highest_node_left_subtree = find_highest_key_node(node.left_child)
node.key = highest_node_left_subtree.key
node.value = highest_node_left_subtree.value
delete_node(node.left_child, highest_node_left_subtree.key)
end
end
def find_node(key)
return find_node(@root, key)
end
def find_parent_node(key)
return nil if @root.key == key
return find_parent_node(@root, key)
end
def inorder_traversal
travel_list = []
inorder_traversal_recursive(travel_list, @root) unless @root == nil
return travel_list
end
private
def find_node(node, key)
return nil if nil == node
if node.key == key
return node
elsif node.key > key
return find_node(node.left_child, key)
else
return find_node(node.right_child, key)
end
end
def find_parent_node(node, key)
return nil if nil == node
return node if node.left_child != nil && node.left_child.key == key
return node if root_node.node != nil && node.right_child.key == key
if node.key > key
return find_parent_node(node.left_child, key)
else
return find_parent_node(node.right_child, key)
end
end
def find_place_for_insert(node, key)
return nil if nil == node
if node.key == key
return nil
elsif node.key > key
return node if nil == node.left_child
return find_place_for_insert(node.left_child, key)
else
return node if nil == node.right_child
return find_place_for_insert(node.right_child, key)
end
end
def find_highest_key_node(node)
return nil if nil == node
highest_key_node = node
while nil != highest_key_node.right_child
highest_key_node = highest_key_node.right_child
end
return highest_key_node
end
def inorder_traversal_recursive(travel_list, node)
return if node == nil
inorder_traversal_recursive(travel_list, node.left_child)
travel_list.push(node)
inorder_traversal_recursive(travel_list, node.right_child)
end
end
def print_travel_node_list(travel_list)
print '[ '
travel_list.each do |node|
print node.key.to_s + "(" + node.value.to_s + ")"
print " "
end
puts ']'
end
def make_example_bst
bst = BinarySearchTree.new
bst.insert_node(8, 1)
bst.insert_node(3, 2)
bst.insert_node(10, 3)
bst.insert_node(2, 4)
bst.insert_node(5, 5)
bst.insert_node(14, 7)
bst.insert_node(11, 12)
bst.insert_node(16, 13)
return bst
end
bst = make_example_bst
print_travel_node_list bst.inorder_traversal
bst.insert_node(4, 10)
print_travel_node_list bst.inorder_traversal
puts "Found 4" if nil != bst.find_node(4)
puts "Found 9" if nil != bst.find_node(9)
bst = make_example_bst
bst.delete_node(5)
print_travel_node_list bst.inorder_traversal
bst = make_example_bst
bst.delete_node(10)
print_travel_node_list bst.inorder_traversal
bst = make_example_bst
bst.delete_node(8)
print_travel_node_list bst.inorder_traversal
|
결과>
[ 2(4) 3(2) 5(5) 8(1) 10(3) 11(12) 14(7) 16(13) ]
[ 2(4) 3(2) 4(10) 5(5) 8(1) 10(3) 11(12) 14(7) 16(13) ]
Found 4
[ 2(4) 3(2) 8(1) 10(3) 11(12) 14(7) 16(13) ]
[ 2(4) 3(2) 5(5) 8(1) 11(12) 14(7) 16(13) ]
[ 2(4) 3(2) 5(5) 10(3) 11(12) 14(7) 16(13) ]
'Dev.Programming > DS/Algorithm' 카테고리의 다른 글
| 인접 행렬로 구현한 Graph - in Ruby (0) | 2009/03/16 |
|---|---|
| Heap - in Ruby (0) | 2009/03/05 |
| Binary Search Tree - in Ruby (0) | 2009/03/04 |
| Binary Tree - in Ruby (0) | 2009/03/04 |
| Deck(Deque, Double-ended Queue) - in Ruby (0) | 2009/03/04 |
| Circular Queue - in Ruby (0) | 2009/03/04 |


