Created
January 7, 2013 06:15
-
-
Save anonymous/4472878 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.