Algorithms and Containers project is Copyright © 2009 Kanwei Li
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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, so duplicate values are overwritten.
A major advantage of RBTreeMap over a Hash is the fact that keys are stored in order and can thus be iterated over in order. This is useful for many datasets.
The implementation is adapted from Robert Sedgewick’s Left Leaning Red-Black Tree implementation, which can be found at www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java
Most methods have O(log n) complexity.
Create and initialize a new empty TreeMap.
# File lib/puppet/rb_tree_map.rb, line 41 def initialize @root = nil @size = 0 end
Deletes the item and key if it’s found, and returns the item. Returns nil if key is not present.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.delete("MA") #=> "Massachusetts"
# File lib/puppet/rb_tree_map.rb, line 121 def delete(key) result = nil if @root return unless has_key? key @root, result = delete_recursive(@root, key) @root.color = :black if @root @size -= 1 end result end
Deletes the item with the largest key and returns the item. Returns nil if key is not present.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.delete_max #=> "Georgia" map.size #=> 1
# File lib/puppet/rb_tree_map.rb, line 167 def delete_max result = nil if @root @root, result = delete_max_recursive(@root) @root.color = :black if @root @size -= 1 end result end
Deletes the item with the smallest key and returns the item. Returns nil if key is not present.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.delete_min #=> "Massachusetts" map.size #=> 1
# File lib/puppet/rb_tree_map.rb, line 147 def delete_min result = nil if @root @root, result = delete_min_recursive(@root) @root.color = :black if @root @size -= 1 end result end
Yields [key, value] pairs in order by key.
# File lib/puppet/rb_tree_map.rb, line 178 def each(&blk) recursive_yield(@root, &blk) end
Returns true if the tree is empty, false otherwise
# File lib/puppet/rb_tree_map.rb, line 133 def empty? @root.nil? end
# File lib/puppet/rb_tree_map.rb, line 182 def first return nil unless @root node = min_recursive(@root) [node.key, node.value] end
Return the item associated with the key, or nil if none found.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.get("GA") #=> "Georgia"
# File lib/puppet/rb_tree_map.rb, line 81 def get(key) node = get_recursive(@root, key) node ? node.value : nil node.value if node end
Return true if key is found in the TreeMap, false otherwise
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.has_key?("GA") #=> true map.has_key?("DE") #=> false
# File lib/puppet/rb_tree_map.rb, line 69 def has_key?(key) !get_recursive(@root, key).nil? end
# File lib/puppet/rb_tree_map.rb, line 188 def last return nil unless @root node = max_recursive(@root) [node.key, node.value] end
Return the largest key in the map.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.max_key #=> "MA"
# File lib/puppet/rb_tree_map.rb, line 108 def max_key @root.nil? ? nil : max_recursive(@root).key end
Return the smallest key in the map.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.min_key #=> "GA"
# File lib/puppet/rb_tree_map.rb, line 96 def min_key @root.nil? ? nil : min_recursive(@root).key end
Insert an item with an associated key into the TreeMap, and returns the item inserted
Complexity: O(log n)
map = Containers::TreeMap.new map.push(“MA”, “Massachusetts”) #=> “Massachusetts” map.get(“MA”) #=> “Massachusetts”
# File lib/puppet/rb_tree_map.rb, line 53 def push(key, value) @root = insert(@root, key, value) @root.color = :black value end
# File lib/puppet/rb_tree_map.rb, line 194 def to_hash @root ? @root.to_hash : {} end