------ art_3377_881405.1197749117421
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Here is a modification that joins both of the latest forks. It answers both
of your challenges:
avl_tree.rb
#!/usr/bin/env ruby -wKU
class TreeNode
attr_accessor :left, :right, :data #, :parent
def initialize(obj il)
@left l
@right l
@dataj
end
def attach_left node
@left ode
end
def attach_right node
@right ode
end
def height
[(left.height rescue 0) , (right.height rescue 0)].max + 1
end
def include? obj
(@data obj) ||
(@left.include? obj rescue false) ||
(@right.include? obj rescue false)
end
def length
len
len + left.length if left
len + right.length if right
end
end
class AVLTree
def initialize
@root il
end
def empty?
! @root
end
def include?(obj)
(! empty?) && (@root.include? obj)
end
def <<(obj)
if empty?
@root reeNode.new obj
else
@root nsert(obj, @root)
end
self
end
def insert(obj, node)
if node nil
node reeNode.new(obj)
elsif obj < node.data
node.left nsert(obj, node.left)
elsif obj > node.data
node.right nsert(obj, node.right)
end
balance node.left.height rescue 0) - (node.right.height rescue 0).abs
if balance > 1
if (obj < node.data)
if (obj < node.left.data)
node otate_with_left_child(node)
end
end
end
node
end
def rotate_with_left_child(node)
new_parent ode.left
node.left ew_parent.right
new_parent.right ode
new_parent
end
def height
empty? ? 0 : @root.height
end
def each
list ist_nodes(@root, [])
for data in list
yield data
end
end
def list_nodes(node, list)
list_nodes(node.left, list) if node.left ! il
list << node.data if node.data ! il
list_nodes(node.right, list) if node.right ! il
list
end
end
test_avl_tree.rb
require "test/unit"
require "avl_tree.rb"
class TestAVLTree < Test::Unit::TestCase
def setup
@tree VLTree.new
end
def test_tree_membership
assert_equal(true, @tree.empty?)
assert_equal(false, @tree.include?(3))
@tree << 3
assert_equal(false, @tree.empty?)
assert_equal(true, @tree.include?(3))
end
def test_tree_height_of_one_or_two_nodes_is_N
@tree << 5
assert_equal 1, @tree.height
@tree << 6
assert_equal 2, @tree.height #changed from 1
end
def test_tree_insertion
assert_equal(true, @tree.empty?)
assert_equal(false, @tree.include?(3))
assert_equal(false, @tree.include?(5))
@tree << 3
@tree << 5
assert_equal(false, @tree.empty?)
assert_equal(true, @tree.include?(5))
assert_equal(true, @tree.include?(3))
end
def test_tree_include_many
0.upto(10) do |i|
assert(! @tree.include?(i), "Tree should not include #{i} yet.")
@tree << i
0.upto(i) do |j|
assert( @tree.include?(j), "Tree should include #{j} already.")
end
end
end
def test_tree_traverse
ary 3,5,17,30,42,54,1,2]
ary.each{|n| @tree << n}
traversal ]
@tree.each{|n| traversal << n}
assert_equal(ary.size, traversal.size)
ary.each{|n| assert traversal.include?(n), "#{n} was not visited in
tree."}
end
def test_balances_left
4.downto(1){|i| @tree << i}
assert(@tree.height<4)
end
def test_balances_right
0.upto(4){|i| @tree << i}
assert(@tree.height<4)
end
end
------ art_3377_881405.1197749117421--