-
Notifications
You must be signed in to change notification settings - Fork 0
/
binarytree.rb
178 lines (157 loc) · 2.98 KB
/
binarytree.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
# 二分探索木
class Tree
# 節の定義
class Node
def initialize(key, data)
@key = key
@data = data
@left = nil
@right = nil
end
attr_accessor :key, :data, :left, :right
end
def initialize
@root = nil
end
# 操作関数
private
# 探索
def search(node, key)
while node
if key == node.key
return node
elsif key < node.key
node = node.left
else
node = node.right
end
end
end
# 挿入
def insert!(node, key, data)
if node == nil
return Node.new(key, data)
elsif key == node.key
node.data = data
elsif key < node.key
node.left = insert!(node.left, key, data)
else
node.right = insert!(node.right, key, data)
end
node
end
# 最小値を探す
def search_min(node)
node = node.left while node.left
node
end
# 最大値を探す
def search_max(node)
node = node.right while node.right
node
end
# 最小値を削除する
def delete_min!(node)
return node.right unless node.left
node.left = delete_min!(node.left)
node
end
# 削除
def delete!(node, key)
data = nil
if node
if key == node.key
data = node.data
if node.left == nil
return node.right, data
elsif node.right == nil
return node.left, data
else
min_node = search_min(node.right)
node.key = min_node.key
node.data = min_node.data
node.right = delete_min!(node.right)
end
elsif key < node.key
node.left, data = delete!(node.left, key)
else
node.right, data = delete!(node.right, key)
end
end
return node, data
end
# 先行順探索
def precedingOrderSearch(node, &func)
if node
func.call(node.key, node.data)
precedingOrderSearch(node.left, &func)
precedingOrderSearch(node.right, &func)
end
end
# 後行順探索
def afterLineOrderSearch(node, &func)
if node
afterLineOrderSearch(node.left, &func)
afterLineOrderSearch(node.right, &func)
func.call(node.key, node.data)
end
end
#中央順探索
def centerOrderSearch(node, &func)
if node
centerOrderSearch(node.left, &func)
func.call(node.key, node.data)
centerOrderSearch(node.right, &func)
end
end
public
# 探索
def find(key)
node = search(@root, key)
if node
node.data
end
end
# 挿入 (更新)
def insert(key, value)
@root = insert!(@root, key, value)
end
# 削除
def delete_key(key)
@root, data = delete!(@root, key)
data
end
# 最小値を求める
def min
if @root
node = search_min(@root)
if node
return node.key, node.data
end
end
end
# 最大値を求める
def max
if @root
node = search_max(@root)
if node
return node.key, node.data
end
end
end
# 先行巡回
def preceding_crawl(&func) # hoge.precedingCrawl do |key, value| のように使う
precedingOrderSearch(@root, &func)
end
# 後行巡回
def after_line_crawl(&func)
afterLineOrderSearch(@root, &func)
end
# 中央巡回
def center_crawl(&func)
centerOrderSearch(@root, &func)
end
def inspect
sprintf("#<Tree:%#x>", self.object_id)
end
end