Skip to content

Instantly share code, notes, and snippets.

Created January 7, 2013 06:15
Show Gist options
  • Save anonymous/4472878 to your computer and use it in GitHub Desktop.
Save anonymous/4472878 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
class BinaryTree
include Enumerable
attr_accessor :key, :data, :left, :right
def initialize(h)
@key = @data = nil
assign_key_data(h)
@left = @right = nil
end
def assign_key_data(obj)
if obj.class == Hash
if obj.has_key?(:key)
@key = obj[:key]
@data = obj[:data]
end
end
end
def empty?
(@left = nil && @right = nil)
end
def size
count = 1
count += @left.size unless @left.nil?
count += @right.size unless @right.nil?
count
end
def each(&block)
@left.each(&block) unless @left.nil?
yield @key
@right.each(&block) unless @right.nil?
end
def find(k)
found = (@key == k) ? self : nil
if match.nil?
found = @left.find(k) if k < @key && !@left.nil?
found = @right.find(k) if k > @key && !@right.nil?
end
found
end
def min_val
min = nil
if @left.nil?
min = {:key => @key, :data => @data}
else
min = @left.min_val
end
min
end
def update(key, data)
end
def<< obj
if obj.class == Hash
if obj.has_key?(:key)
insert(obj)
end
end
end
def insert(obj)
if obj[:key] < @key
@left = push_or_attach(obj, @left)
elsif obj[:key] > @key
@right = push_or_attach(obj, @right)
end
end
def push_or_attach(obj, node)
if node.nil?
### TODO: Check if :key and :data exist in obj and that obj is a Hash
node = BinaryTree.new(obj)
else
node << obj
end
node
end
def print(level = 0, options={})
if options.has_key?(:inorder) || options.empty?
@left.print(level+1,options) unless @left.nil?
puts "#{@key} "
@right.print(level+1,options) unless @right.nil?
elsif options.has_key?(:preorder)
puts "#{@key} "
@left.print(level+1,options) unless @left.nil?
@right.print(level+1,options) unless @right.nil?
elsif options.has_key?(:postorder)
@left.print(level+1,options) unless @left.nil?
@right.print(level+1,options) unless @right.nil?
puts "#{@key} "
end
end
def remove(key, parent = nil)
result = nil
if @key > key
result = @left.remove(key, self) unless @left.nil?
elsif @key < key
result = @right.remove(key,self) unless @right.nil?
else
rearrange(key, parent)
end
result
end
def rearrange(key, parent)
if !@left.nil? && !@right.nil?
min = @right.min_val
@key,@data = min[:key], min[:data]
right.remove(@key, self)
elsif parent.left == self
parent.left = (!@left.nil?) ? @left : @right
elsif parent.right == self
parent.right = (!@left.nil?) ? @left : @right
end
end
end
# Test
test = [20,4,10,5,-1,22,2313,22,22]
bt = BinaryTree.new({:key=>1, :data=>nil})
test.each do |n|
bt << {:key => n, :data=>nil}
end
bt.print(0,{:preorder=>nil})
puts "removing elements"
puts "removing 4"
bt.remove(4)
bt.print
@bluetwin
Copy link

bluetwin commented Jan 7, 2013

Since there wasn't much in the way of easily found code online, A Binary Search Tree in Ruby.

Oh and Github needs to fix their Gist and Github connections, it wouldn't let me connect the account ,even though I was already signed in. So this is bluetwin's gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment