Skip to content

Commit

Permalink
Iterate over trees iteratively instead of recursively
Browse files Browse the repository at this point in the history
  • Loading branch information
kanwei committed Jul 20, 2008
1 parent 67d1338 commit 72f0c2d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 27 deletions.
34 changes: 21 additions & 13 deletions lib/containers/rb_tree_map.rb
@@ -1,3 +1,4 @@
require 'containers/stack'
=begin rdoc
A RBTreeMap is a map that is stored in sorted order based on the order of its keys. This ordering is
determined by applying the function <=> to compare the keys. No duplicate values for keys are allowed,
Expand Down Expand Up @@ -178,9 +179,25 @@ def delete_max
result
end

# Iterates over the TreeMap from smallest to largest element
def each(&block)
@root.nil? ? nil : each_recursive(@root, block)
# Iterates over the TreeMap from smallest to largest element. Iterative approach.
def each
return nil unless @root
stack = Containers::Stack.new
cursor = @root
loop do
if cursor
stack.push(cursor)
cursor = cursor.left
else
unless stack.empty?
cursor = stack.pop
yield(cursor.key, cursor.value)
cursor = cursor.right
else
break
end
end
end
end

class Node # :nodoc: all
Expand Down Expand Up @@ -272,16 +289,7 @@ def fixup
update_size
end
end

def each_recursive(node, block)
return if node.nil?

each_recursive(node.left, block)
block[node.key, node.value]
each_recursive(node.right, block)
end
private :each_recursive


def delete_recursive(node, key)
if (key <=> node.key) == -1
node.move_red_left if ( !isred(node.left) && !isred(node.left.left) )
Expand Down
36 changes: 22 additions & 14 deletions lib/containers/splay_tree_map.rb
@@ -1,3 +1,4 @@
require 'containers/stack'
=begin rdoc
A SplayTreeMap is a map that is stored in ascending order of its keys, determined by applying
the function <=> to compare keys. No duplicate values for keys are allowed, so new values of a key
Expand All @@ -12,7 +13,7 @@
when keys are added in sorted order, causing the tree to have a height of the number of items added.
=end
class Containers::SplayTreeMap
class Containers::SplayTreeMap
include Enumerable

# Create and initialize a new empty SplayTreeMap.
Expand Down Expand Up @@ -181,9 +182,25 @@ def delete(key)
deleted
end

# Iterates over the SplayTreeMap in ascending order.
def each(&block)
@root.nil? ? nil : each_recursive(@root, block)
# Iterates over the SplayTreeMap in ascending order. Uses an iterative, not recursive, approach.
def each
return nil unless @root
stack = Containers::Stack.new
cursor = @root
loop do
if cursor
stack.push(cursor)
cursor = cursor.left
else
unless stack.empty?
cursor = stack.pop
yield(cursor.key, cursor.value)
cursor = cursor.right
else
break
end
end
end
end

class Node # :nodoc: all
Expand Down Expand Up @@ -253,14 +270,5 @@ def height_recursive(node)
left_height > right_height ? left_height : right_height
end
private :height_recursive

# Recursively iterate over elements in ascending order
def each_recursive(node, block)
return if node.nil?

each_recursive(node.left, block)
block[node.key, node.value]
each_recursive(node.right, block)
end
private :each_recursive

end

0 comments on commit 72f0c2d

Please sign in to comment.