14. class RBTree
attr_reader :key, :value
attr_accessor :color, :left, :right getのみ、およびget/setの
def initialize(key, value) 簡易定義
@key, @value = key, value
@left = @right = EMPTY
# new node is added as RED
@color = :RED
end
def make_as_root
@color = :BLACK
end
def empty?
false
end
def red?
@color == :RED
end
def black?
@color == :BLACK
end
15. class RBTree
attr_reader :key, :value
attr_accessor :color, :left, :right
def initialize(key, value)
@key, @value = key, value
@left = @right = EMPTY
# new node is added as RED
@color = :RED
end
def make_as_root
@color = :BLACK
end
def empty?
false
end メソッド名末尾に?が使える
def red?
@color == :RED
end
def black?
@color == :BLACK
end
16. # returns new tree
def insert(key, value)
case key <=> @key 挿入は再帰で実装
when -1
@left = @left.insert(key,value)
when 0
@value = value
when 1
@right=@right.insert(key,value)
end
# Rebalance of LL red-black trees
insert_rotate_left.
insert_rotate_right.
insert_color_flip
end
# returns value
def retrieve(key)
ptr = self
while !ptr.empty?
case key <=> ptr.key
when -1
ptr = ptr.left
when 0
return ptr.value
when 1
ptr = ptr.right
end
end
nil
end
17. # returns new tree
def insert(key, value)
case key <=> @key
when -1
@left = @left.insert(key,value)
when 0
@value = value
when 1
@right=@right.insert(key,value)
end
# Rebalance of LL red-black trees
insert_rotate_left.
insert_rotate_right.
insert_color_flip
end
# returns value
def retrieve(key)
ptr = self 参照はループで実装
while !ptr.empty?
case key <=> ptr.key
when -1
ptr = ptr.left
when 0
return ptr.value
when 1
ptr = ptr.right
end
end
nil
end
18. class EmptyTree < RBTree
def initialize
@value = nil
@color = :BLACK
end
def empty?
true
end
# returns new_root
def insert(key, value)
RBTree.new(key, value)
末端への挿入により木が
end 大きくなる
def height
0
end
end
private_constant :EmptyTree
EMPTY = EmptyTree.new.freeze
19. # Do roate_left after insert if needed
def insert_rotate_left
if @left.black? and @right.red?
rotate_left
else
self
end
end
# Do rotate_right after insert if needed
def insert_rotate_right
if @left.red? and @left.left.red?
rotate_right
else
self
end リズムよく、山の形の
end 定義が連なる
# Do color_flip after insert if needed
def insert_color_flip
if @left.red? and @right.red?
color_flip
else
self
end
end
def swap_color(other)
@color, other.color = other.color, @color
end
20. # Right single rotation
#
# b d 手続き的な木の回転...
# / /
# a D -> B E
# / /
# c E a c
#
def rotate_left
root = @right
@right = root.left
root.left = self
root.swap_color(root.left)
root
end
# Left single rotation
#
# d b
# / /
# B e -> A D
# / /
# A c c e
#
def rotate_right
root = @left
@left = root.right
root.right = self
root.swap_color(root.right)
root
end
21. # Right single rotation
#
# b d
# / /
# a D -> B E
# / /
# c E a c
#
def rotate_left
root = @right
@right = root.left
root.left = self
root.swap_color(root.left)
root
end
# Left single rotation
#
# d b 逆方向もベタ書き...
# / /
# B e -> A D
# / /
# A c c e
#
def rotate_right
root = @left
@left = root.right
root.right = self
root.swap_color(root.right)
root
end
22. class RBTreeMap
class << self
alias newInstance new
end
def initialize
@root = RBTree::EMPTY
end
def get(key)
@root.retrieve(key)
end 赤黒木(RBTree)を使った
def put(key, value) 連想配列(RBTreeMap)
@root = @root.insert(key, value)
@root.make_as_root
value
end
def height
@root.height
end
end
※CRuby完全互換
https://github.com/nahi/javaone2012-benchmark