stakach-algorithms 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +99 -97
- data/Rakefile +15 -27
- data/ext/algorithms/string/extconf.rb +4 -4
- data/ext/algorithms/string/string.c +68 -70
- data/ext/containers/bst/bst.c +249 -249
- data/ext/containers/bst/extconf.rb +4 -4
- data/ext/containers/deque/deque.c +248 -248
- data/ext/containers/deque/extconf.rb +4 -4
- data/ext/containers/rbtree_map/extconf.rb +4 -4
- data/ext/containers/rbtree_map/rbtree.c +500 -500
- data/ext/containers/splaytree_map/extconf.rb +4 -4
- data/ext/containers/splaytree_map/splaytree.c +421 -421
- data/lib/algorithms.rb +69 -69
- data/lib/algorithms/search.rb +85 -85
- data/lib/algorithms/sort.rb +242 -242
- data/lib/algorithms/string.rb +10 -10
- data/lib/algorithms/version.rb +3 -3
- data/lib/containers/deque.rb +176 -176
- data/lib/containers/heap.rb +501 -506
- data/lib/containers/kd_tree.rb +112 -112
- data/lib/containers/priority_queue.rb +116 -116
- data/lib/containers/queue.rb +71 -71
- data/lib/containers/rb_tree_map.rb +402 -402
- data/lib/containers/splay_tree_map.rb +273 -273
- data/lib/containers/stack.rb +70 -70
- data/lib/containers/suffix_array.rb +71 -71
- data/lib/containers/trie.rb +187 -187
- data/spec/bst_gc_mark_spec.rb +25 -0
- data/spec/bst_spec.rb +25 -0
- data/spec/deque_gc_mark_spec.rb +17 -0
- data/spec/deque_spec.rb +107 -0
- data/spec/heap_spec.rb +130 -0
- data/spec/helper.rb +4 -0
- data/spec/kd_expected_out.txt +10000 -0
- data/spec/kd_test_in.txt +10000 -0
- data/spec/kd_tree_spec.rb +33 -0
- data/spec/map_gc_mark_spec.rb +28 -0
- data/spec/priority_queue_spec.rb +74 -0
- data/spec/queue_spec.rb +60 -0
- data/spec/rb_tree_map_spec.rb +122 -0
- data/spec/search_spec.rb +27 -0
- data/spec/sort_spec.rb +26 -0
- data/spec/splay_tree_map_spec.rb +105 -0
- data/spec/stack_spec.rb +59 -0
- data/spec/string_spec.rb +12 -0
- data/spec/suffix_array_spec.rb +39 -0
- data/spec/trie_spec.rb +58 -0
- metadata +60 -4
| @@ -1,273 +1,273 @@ | |
| 1 | 
            -
            require 'containers/stack'
         | 
| 2 | 
            -
            =begin rdoc
         | 
| 3 | 
            -
                A SplayTreeMap is a map that is stored in ascending order of its keys, determined by applying
         | 
| 4 | 
            -
                the function <=> to compare keys. No duplicate values for keys are allowed, so new values of a key
         | 
| 5 | 
            -
                overwrites the old value of the key.
         | 
| 6 | 
            -
                
         | 
| 7 | 
            -
                A major advantage of SplayTreeMap over a Hash is the fact that keys are stored in order and can thus be
         | 
| 8 | 
            -
                iterated over in order. Also, Splay Trees are self-optimizing as recently accessed nodes stay near
         | 
| 9 | 
            -
                the root and are easily re-accessed later. Splay Trees are also more simply implemented than Red-Black
         | 
| 10 | 
            -
                trees.
         | 
| 11 | 
            -
                
         | 
| 12 | 
            -
                Splay trees have amortized O(log n) performance for most methods, but are O(n) worst case. This happens
         | 
| 13 | 
            -
                when keys are added in sorted order, causing the tree to have a height of the number of items added.
         | 
| 14 | 
            -
                
         | 
| 15 | 
            -
            =end
         | 
| 16 | 
            -
            module Algorithms
         | 
| 17 | 
            -
              module Containers
         | 
| 18 | 
            -
                class RubySplayTreeMap
         | 
| 19 | 
            -
                  include Enumerable
         | 
| 20 | 
            -
              
         | 
| 21 | 
            -
                  Node = Struct.new(:key, :value, :left, :right)
         | 
| 22 | 
            -
              
         | 
| 23 | 
            -
                  # Create and initialize a new empty SplayTreeMap.
         | 
| 24 | 
            -
                  def initialize
         | 
| 25 | 
            -
                    @size = 0
         | 
| 26 | 
            -
                    clear
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
              
         | 
| 29 | 
            -
                  # Insert an item with an associated key into the SplayTreeMap, and returns the item inserted
         | 
| 30 | 
            -
                  #
         | 
| 31 | 
            -
                  # Complexity: amortized O(log n)
         | 
| 32 | 
            -
                  #
         | 
| 33 | 
            -
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 34 | 
            -
                  #   map.push("MA", "Massachusetts") #=> "Massachusetts"
         | 
| 35 | 
            -
                  #   map.get("MA") #=> "Massachusetts"
         | 
| 36 | 
            -
                  def push(key, value)
         | 
| 37 | 
            -
                    if @root.nil?
         | 
| 38 | 
            -
                      @root = Node.new(key, value, nil, nil)
         | 
| 39 | 
            -
                      @size = 1
         | 
| 40 | 
            -
                      return value
         | 
| 41 | 
            -
                    end
         | 
| 42 | 
            -
                    splay(key)
         | 
| 43 | 
            -
                
         | 
| 44 | 
            -
                    cmp = (key <=> @root.key)
         | 
| 45 | 
            -
                    if cmp == 0
         | 
| 46 | 
            -
                      @root.value = value
         | 
| 47 | 
            -
                      return value
         | 
| 48 | 
            -
                    end
         | 
| 49 | 
            -
                    node = Node.new(key, value, nil, nil)
         | 
| 50 | 
            -
                    if cmp < 1
         | 
| 51 | 
            -
                      node.left = @root.left
         | 
| 52 | 
            -
                      node.right = @root
         | 
| 53 | 
            -
                      @root.left = nil
         | 
| 54 | 
            -
                    else
         | 
| 55 | 
            -
                      node.right = @root.right
         | 
| 56 | 
            -
                      node.left = @root
         | 
| 57 | 
            -
                      @root.right = nil
         | 
| 58 | 
            -
                    end
         | 
| 59 | 
            -
                    @root = node
         | 
| 60 | 
            -
                    @size += 1
         | 
| 61 | 
            -
                    value
         | 
| 62 | 
            -
                  end
         | 
| 63 | 
            -
                  alias_method :[]=, :push
         | 
| 64 | 
            -
              
         | 
| 65 | 
            -
                  # Return the number of items in the SplayTreeMap.
         | 
| 66 | 
            -
                  #
         | 
| 67 | 
            -
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 68 | 
            -
                  #   map.push("MA", "Massachusetts")
         | 
| 69 | 
            -
                  #   map.push("GA", "Georgia")
         | 
| 70 | 
            -
                  #   map.size #=> 2
         | 
| 71 | 
            -
                  def size
         | 
| 72 | 
            -
                    @size
         | 
| 73 | 
            -
                  end
         | 
| 74 | 
            -
              
         | 
| 75 | 
            -
                  # Remove all elements from the SplayTreeMap
         | 
| 76 | 
            -
                  #
         | 
| 77 | 
            -
                  # Complexity: O(1)
         | 
| 78 | 
            -
                  #
         | 
| 79 | 
            -
                  def clear
         | 
| 80 | 
            -
                    @root = nil
         | 
| 81 | 
            -
                    @size = 0
         | 
| 82 | 
            -
                    @header = Node.new(nil, nil, nil, nil)
         | 
| 83 | 
            -
                  end
         | 
| 84 | 
            -
              
         | 
| 85 | 
            -
                  # Return the height of the tree structure in the SplayTreeMap.
         | 
| 86 | 
            -
                  #
         | 
| 87 | 
            -
                  # Complexity: O(log n)
         | 
| 88 | 
            -
                  #
         | 
| 89 | 
            -
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 90 | 
            -
                  #   map.push("MA", "Massachusetts")
         | 
| 91 | 
            -
                  #   map.push("GA", "Georgia")
         | 
| 92 | 
            -
                  #   map.height #=> 2
         | 
| 93 | 
            -
                  def height
         | 
| 94 | 
            -
                    height_recursive(@root)
         | 
| 95 | 
            -
                  end
         | 
| 96 | 
            -
              
         | 
| 97 | 
            -
                  # Return true if key is found in the SplayTreeMap, false otherwise.
         | 
| 98 | 
            -
                  #
         | 
| 99 | 
            -
                  # Complexity: amortized O(log n)
         | 
| 100 | 
            -
                  #
         | 
| 101 | 
            -
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 102 | 
            -
                  #   map["MA"] = "Massachusetts"
         | 
| 103 | 
            -
                  #   map["GA"] = "Georgia"
         | 
| 104 | 
            -
                  #   map.has_key?("GA") #=> true
         | 
| 105 | 
            -
                  #   map.has_key?("DE") #=> false
         | 
| 106 | 
            -
                  def has_key?(key)
         | 
| 107 | 
            -
                    !get(key).nil?
         | 
| 108 | 
            -
                  end
         | 
| 109 | 
            -
              
         | 
| 110 | 
            -
                  # Return the item associated with the key, or nil if none found.
         | 
| 111 | 
            -
                  #
         | 
| 112 | 
            -
                  # Complexity: amortized O(log n)
         | 
| 113 | 
            -
                  #
         | 
| 114 | 
            -
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 115 | 
            -
                  #   map.push("MA", "Massachusetts")
         | 
| 116 | 
            -
                  #   map.push("GA", "Georgia")
         | 
| 117 | 
            -
                  #   map.get("GA") #=> "Georgia"
         | 
| 118 | 
            -
                  def get(key)
         | 
| 119 | 
            -
                    return nil if @root.nil?
         | 
| 120 | 
            -
                
         | 
| 121 | 
            -
                    splay(key)
         | 
| 122 | 
            -
                    (@root.key <=> key) == 0 ? @root.value : nil
         | 
| 123 | 
            -
                  end
         | 
| 124 | 
            -
                  alias_method :[], :get
         | 
| 125 | 
            -
              
         | 
| 126 | 
            -
                  # Return the smallest [key, value] pair in the SplayTreeMap, or nil if the tree is empty.
         | 
| 127 | 
            -
                  #
         | 
| 128 | 
            -
                  # Complexity: amortized O(log n)
         | 
| 129 | 
            -
                  #
         | 
| 130 | 
            -
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 131 | 
            -
                  #   map["MA"] = "Massachusetts"
         | 
| 132 | 
            -
                  #   map["GA"] = "Georgia"
         | 
| 133 | 
            -
                  #   map.min #=> ["GA", "Georgia"]
         | 
| 134 | 
            -
                  def min
         | 
| 135 | 
            -
                    return nil if @root.nil?
         | 
| 136 | 
            -
                    n = @root
         | 
| 137 | 
            -
                    while n.left
         | 
| 138 | 
            -
                      n = n.left
         | 
| 139 | 
            -
                    end
         | 
| 140 | 
            -
                    splay(n.key)
         | 
| 141 | 
            -
                    return [n.key, n.value]
         | 
| 142 | 
            -
                  end
         | 
| 143 | 
            -
              
         | 
| 144 | 
            -
                  # Return the largest [key, value] pair in the SplayTreeMap, or nil if the tree is empty.
         | 
| 145 | 
            -
                  #
         | 
| 146 | 
            -
                  # Complexity: amortized O(log n)
         | 
| 147 | 
            -
                  #
         | 
| 148 | 
            -
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 149 | 
            -
                  #   map["MA"] = "Massachusetts"
         | 
| 150 | 
            -
                  #   map["GA"] = "Georgia"
         | 
| 151 | 
            -
                  #   map.max #=> ["MA", "Massachusetts"]
         | 
| 152 | 
            -
                  def max
         | 
| 153 | 
            -
                    return nil if @root.nil?
         | 
| 154 | 
            -
                    n = @root
         | 
| 155 | 
            -
                    while n.right
         | 
| 156 | 
            -
                      n = n.right
         | 
| 157 | 
            -
                    end
         | 
| 158 | 
            -
                    splay(n.key)
         | 
| 159 | 
            -
                    return [n.key, n.value]
         | 
| 160 | 
            -
                  end
         | 
| 161 | 
            -
              
         | 
| 162 | 
            -
                  # Deletes the item and key if it's found, and returns the item. Returns nil
         | 
| 163 | 
            -
                  # if key is not present.
         | 
| 164 | 
            -
                  #
         | 
| 165 | 
            -
                  # Complexity: amortized O(log n)
         | 
| 166 | 
            -
                  #
         | 
| 167 | 
            -
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 168 | 
            -
                  #   map["MA"] = "Massachusetts"
         | 
| 169 | 
            -
                  #   map["GA"] = "Georgia"
         | 
| 170 | 
            -
                  #   map.delete("GA") #=> "Georgia"
         | 
| 171 | 
            -
                  #   map.delete("DE") #=> nil
         | 
| 172 | 
            -
                  def delete(key)
         | 
| 173 | 
            -
                    return nil if @root.nil?
         | 
| 174 | 
            -
                    deleted = nil
         | 
| 175 | 
            -
                    splay(key)
         | 
| 176 | 
            -
                    if (key <=> @root.key) == 0 # The key exists
         | 
| 177 | 
            -
                      deleted = @root.value
         | 
| 178 | 
            -
                      if @root.left.nil?
         | 
| 179 | 
            -
                        @root = @root.right
         | 
| 180 | 
            -
                      else
         | 
| 181 | 
            -
                        x = @root.right
         | 
| 182 | 
            -
                        @root = @root.left
         | 
| 183 | 
            -
                        splay(key)
         | 
| 184 | 
            -
                        @root.right = x
         | 
| 185 | 
            -
                      end
         | 
| 186 | 
            -
                    end
         | 
| 187 | 
            -
                    deleted
         | 
| 188 | 
            -
                  end
         | 
| 189 | 
            -
              
         | 
| 190 | 
            -
                  # Iterates over the SplayTreeMap in ascending order. Uses an iterative, not recursive, approach.
         | 
| 191 | 
            -
                  def each
         | 
| 192 | 
            -
                    return nil unless @root
         | 
| 193 | 
            -
                    stack = Stack.new
         | 
| 194 | 
            -
                    cursor = @root
         | 
| 195 | 
            -
                    loop do
         | 
| 196 | 
            -
                      if cursor
         | 
| 197 | 
            -
                        stack.push(cursor)
         | 
| 198 | 
            -
                        cursor = cursor.left
         | 
| 199 | 
            -
                      else
         | 
| 200 | 
            -
                        unless stack.empty?
         | 
| 201 | 
            -
                          cursor = stack.pop
         | 
| 202 | 
            -
                          yield(cursor.key, cursor.value)
         | 
| 203 | 
            -
                          cursor = cursor.right
         | 
| 204 | 
            -
                        else
         | 
| 205 | 
            -
                          break
         | 
| 206 | 
            -
                        end
         | 
| 207 | 
            -
                      end
         | 
| 208 | 
            -
                    end
         | 
| 209 | 
            -
                  end
         | 
| 210 | 
            -
              
         | 
| 211 | 
            -
                  # Moves a key to the root, updating the structure in each step.
         | 
| 212 | 
            -
                  def splay(key)
         | 
| 213 | 
            -
                    l, r = @header, @header
         | 
| 214 | 
            -
                    t = @root
         | 
| 215 | 
            -
                    @header.left, @header.right = nil, nil
         | 
| 216 | 
            -
                
         | 
| 217 | 
            -
                    loop do
         | 
| 218 | 
            -
                      if (key <=> t.key) == -1
         | 
| 219 | 
            -
                        break unless t.left
         | 
| 220 | 
            -
                        if (key <=> t.left.key) == -1
         | 
| 221 | 
            -
                          y = t.left
         | 
| 222 | 
            -
                          t.left = y.right
         | 
| 223 | 
            -
                          y.right = t
         | 
| 224 | 
            -
                          t = y
         | 
| 225 | 
            -
                          break unless t.left
         | 
| 226 | 
            -
                        end
         | 
| 227 | 
            -
                        r.left = t
         | 
| 228 | 
            -
                        r = t
         | 
| 229 | 
            -
                        t = t.left
         | 
| 230 | 
            -
                      elsif (key <=> t.key) == 1
         | 
| 231 | 
            -
                        break unless t.right
         | 
| 232 | 
            -
                        if (key <=> t.right.key) == 1
         | 
| 233 | 
            -
                          y = t.right
         | 
| 234 | 
            -
                          t.right = y.left
         | 
| 235 | 
            -
                          y.left = t
         | 
| 236 | 
            -
                          t = y
         | 
| 237 | 
            -
                          break unless t.right
         | 
| 238 | 
            -
                        end
         | 
| 239 | 
            -
                        l.right = t
         | 
| 240 | 
            -
                        l = t
         | 
| 241 | 
            -
                        t = t.right
         | 
| 242 | 
            -
                      else
         | 
| 243 | 
            -
                        break
         | 
| 244 | 
            -
                	    end
         | 
| 245 | 
            -
                    end
         | 
| 246 | 
            -
                    l.right = t.left
         | 
| 247 | 
            -
                    r.left = t.right
         | 
| 248 | 
            -
                    t.left = @header.right
         | 
| 249 | 
            -
                    t.right = @header.left
         | 
| 250 | 
            -
                    @root = t
         | 
| 251 | 
            -
                  end
         | 
| 252 | 
            -
                  private :splay
         | 
| 253 | 
            -
              
         | 
| 254 | 
            -
                  # Recursively determine height
         | 
| 255 | 
            -
                  def height_recursive(node)
         | 
| 256 | 
            -
                    return 0 if node.nil?
         | 
| 257 | 
            -
                
         | 
| 258 | 
            -
                    left_height   = 1 + height_recursive(node.left)
         | 
| 259 | 
            -
                    right_height  = 1 + height_recursive(node.right)
         | 
| 260 | 
            -
                
         | 
| 261 | 
            -
                    left_height > right_height ? left_height : right_height
         | 
| 262 | 
            -
                  end
         | 
| 263 | 
            -
                  private :height_recursive
         | 
| 264 | 
            -
                end
         | 
| 265 | 
            -
              end
         | 
| 266 | 
            -
             | 
| 267 | 
            -
              begin
         | 
| 268 | 
            -
                require 'CSplayTreeMap'
         | 
| 269 | 
            -
                Containers::SplayTreeMap = Containers::CSplayTreeMap
         | 
| 270 | 
            -
              rescue Object # C Version could not be found, try ruby version
         | 
| 271 | 
            -
                Containers::SplayTreeMap = Containers::RubySplayTreeMap
         | 
| 272 | 
            -
              end
         | 
| 273 | 
            -
            end
         | 
| 1 | 
            +
            require 'containers/stack'
         | 
| 2 | 
            +
            =begin rdoc
         | 
| 3 | 
            +
                A SplayTreeMap is a map that is stored in ascending order of its keys, determined by applying
         | 
| 4 | 
            +
                the function <=> to compare keys. No duplicate values for keys are allowed, so new values of a key
         | 
| 5 | 
            +
                overwrites the old value of the key.
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                A major advantage of SplayTreeMap over a Hash is the fact that keys are stored in order and can thus be
         | 
| 8 | 
            +
                iterated over in order. Also, Splay Trees are self-optimizing as recently accessed nodes stay near
         | 
| 9 | 
            +
                the root and are easily re-accessed later. Splay Trees are also more simply implemented than Red-Black
         | 
| 10 | 
            +
                trees.
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                Splay trees have amortized O(log n) performance for most methods, but are O(n) worst case. This happens
         | 
| 13 | 
            +
                when keys are added in sorted order, causing the tree to have a height of the number of items added.
         | 
| 14 | 
            +
                
         | 
| 15 | 
            +
            =end
         | 
| 16 | 
            +
            module Algorithms
         | 
| 17 | 
            +
              module Containers
         | 
| 18 | 
            +
                class RubySplayTreeMap
         | 
| 19 | 
            +
                  include Enumerable
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
                  Node = Struct.new(:key, :value, :left, :right)
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
                  # Create and initialize a new empty SplayTreeMap.
         | 
| 24 | 
            +
                  def initialize
         | 
| 25 | 
            +
                    @size = 0
         | 
| 26 | 
            +
                    clear
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
                  # Insert an item with an associated key into the SplayTreeMap, and returns the item inserted
         | 
| 30 | 
            +
                  #
         | 
| 31 | 
            +
                  # Complexity: amortized O(log n)
         | 
| 32 | 
            +
                  #
         | 
| 33 | 
            +
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 34 | 
            +
                  #   map.push("MA", "Massachusetts") #=> "Massachusetts"
         | 
| 35 | 
            +
                  #   map.get("MA") #=> "Massachusetts"
         | 
| 36 | 
            +
                  def push(key, value)
         | 
| 37 | 
            +
                    if @root.nil?
         | 
| 38 | 
            +
                      @root = Node.new(key, value, nil, nil)
         | 
| 39 | 
            +
                      @size = 1
         | 
| 40 | 
            +
                      return value
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                    splay(key)
         | 
| 43 | 
            +
                
         | 
| 44 | 
            +
                    cmp = (key <=> @root.key)
         | 
| 45 | 
            +
                    if cmp == 0
         | 
| 46 | 
            +
                      @root.value = value
         | 
| 47 | 
            +
                      return value
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                    node = Node.new(key, value, nil, nil)
         | 
| 50 | 
            +
                    if cmp < 1
         | 
| 51 | 
            +
                      node.left = @root.left
         | 
| 52 | 
            +
                      node.right = @root
         | 
| 53 | 
            +
                      @root.left = nil
         | 
| 54 | 
            +
                    else
         | 
| 55 | 
            +
                      node.right = @root.right
         | 
| 56 | 
            +
                      node.left = @root
         | 
| 57 | 
            +
                      @root.right = nil
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                    @root = node
         | 
| 60 | 
            +
                    @size += 1
         | 
| 61 | 
            +
                    value
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                  alias_method :[]=, :push
         | 
| 64 | 
            +
              
         | 
| 65 | 
            +
                  # Return the number of items in the SplayTreeMap.
         | 
| 66 | 
            +
                  #
         | 
| 67 | 
            +
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 68 | 
            +
                  #   map.push("MA", "Massachusetts")
         | 
| 69 | 
            +
                  #   map.push("GA", "Georgia")
         | 
| 70 | 
            +
                  #   map.size #=> 2
         | 
| 71 | 
            +
                  def size
         | 
| 72 | 
            +
                    @size
         | 
| 73 | 
            +
                  end
         | 
| 74 | 
            +
              
         | 
| 75 | 
            +
                  # Remove all elements from the SplayTreeMap
         | 
| 76 | 
            +
                  #
         | 
| 77 | 
            +
                  # Complexity: O(1)
         | 
| 78 | 
            +
                  #
         | 
| 79 | 
            +
                  def clear
         | 
| 80 | 
            +
                    @root = nil
         | 
| 81 | 
            +
                    @size = 0
         | 
| 82 | 
            +
                    @header = Node.new(nil, nil, nil, nil)
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
              
         | 
| 85 | 
            +
                  # Return the height of the tree structure in the SplayTreeMap.
         | 
| 86 | 
            +
                  #
         | 
| 87 | 
            +
                  # Complexity: O(log n)
         | 
| 88 | 
            +
                  #
         | 
| 89 | 
            +
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 90 | 
            +
                  #   map.push("MA", "Massachusetts")
         | 
| 91 | 
            +
                  #   map.push("GA", "Georgia")
         | 
| 92 | 
            +
                  #   map.height #=> 2
         | 
| 93 | 
            +
                  def height
         | 
| 94 | 
            +
                    height_recursive(@root)
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
              
         | 
| 97 | 
            +
                  # Return true if key is found in the SplayTreeMap, false otherwise.
         | 
| 98 | 
            +
                  #
         | 
| 99 | 
            +
                  # Complexity: amortized O(log n)
         | 
| 100 | 
            +
                  #
         | 
| 101 | 
            +
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 102 | 
            +
                  #   map["MA"] = "Massachusetts"
         | 
| 103 | 
            +
                  #   map["GA"] = "Georgia"
         | 
| 104 | 
            +
                  #   map.has_key?("GA") #=> true
         | 
| 105 | 
            +
                  #   map.has_key?("DE") #=> false
         | 
| 106 | 
            +
                  def has_key?(key)
         | 
| 107 | 
            +
                    !get(key).nil?
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
              
         | 
| 110 | 
            +
                  # Return the item associated with the key, or nil if none found.
         | 
| 111 | 
            +
                  #
         | 
| 112 | 
            +
                  # Complexity: amortized O(log n)
         | 
| 113 | 
            +
                  #
         | 
| 114 | 
            +
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 115 | 
            +
                  #   map.push("MA", "Massachusetts")
         | 
| 116 | 
            +
                  #   map.push("GA", "Georgia")
         | 
| 117 | 
            +
                  #   map.get("GA") #=> "Georgia"
         | 
| 118 | 
            +
                  def get(key)
         | 
| 119 | 
            +
                    return nil if @root.nil?
         | 
| 120 | 
            +
                
         | 
| 121 | 
            +
                    splay(key)
         | 
| 122 | 
            +
                    (@root.key <=> key) == 0 ? @root.value : nil
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
                  alias_method :[], :get
         | 
| 125 | 
            +
              
         | 
| 126 | 
            +
                  # Return the smallest [key, value] pair in the SplayTreeMap, or nil if the tree is empty.
         | 
| 127 | 
            +
                  #
         | 
| 128 | 
            +
                  # Complexity: amortized O(log n)
         | 
| 129 | 
            +
                  #
         | 
| 130 | 
            +
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 131 | 
            +
                  #   map["MA"] = "Massachusetts"
         | 
| 132 | 
            +
                  #   map["GA"] = "Georgia"
         | 
| 133 | 
            +
                  #   map.min #=> ["GA", "Georgia"]
         | 
| 134 | 
            +
                  def min
         | 
| 135 | 
            +
                    return nil if @root.nil?
         | 
| 136 | 
            +
                    n = @root
         | 
| 137 | 
            +
                    while n.left
         | 
| 138 | 
            +
                      n = n.left
         | 
| 139 | 
            +
                    end
         | 
| 140 | 
            +
                    splay(n.key)
         | 
| 141 | 
            +
                    return [n.key, n.value]
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
              
         | 
| 144 | 
            +
                  # Return the largest [key, value] pair in the SplayTreeMap, or nil if the tree is empty.
         | 
| 145 | 
            +
                  #
         | 
| 146 | 
            +
                  # Complexity: amortized O(log n)
         | 
| 147 | 
            +
                  #
         | 
| 148 | 
            +
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 149 | 
            +
                  #   map["MA"] = "Massachusetts"
         | 
| 150 | 
            +
                  #   map["GA"] = "Georgia"
         | 
| 151 | 
            +
                  #   map.max #=> ["MA", "Massachusetts"]
         | 
| 152 | 
            +
                  def max
         | 
| 153 | 
            +
                    return nil if @root.nil?
         | 
| 154 | 
            +
                    n = @root
         | 
| 155 | 
            +
                    while n.right
         | 
| 156 | 
            +
                      n = n.right
         | 
| 157 | 
            +
                    end
         | 
| 158 | 
            +
                    splay(n.key)
         | 
| 159 | 
            +
                    return [n.key, n.value]
         | 
| 160 | 
            +
                  end
         | 
| 161 | 
            +
              
         | 
| 162 | 
            +
                  # Deletes the item and key if it's found, and returns the item. Returns nil
         | 
| 163 | 
            +
                  # if key is not present.
         | 
| 164 | 
            +
                  #
         | 
| 165 | 
            +
                  # Complexity: amortized O(log n)
         | 
| 166 | 
            +
                  #
         | 
| 167 | 
            +
                  #   map = Algorithms::Containers::SplayTreeMap.new
         | 
| 168 | 
            +
                  #   map["MA"] = "Massachusetts"
         | 
| 169 | 
            +
                  #   map["GA"] = "Georgia"
         | 
| 170 | 
            +
                  #   map.delete("GA") #=> "Georgia"
         | 
| 171 | 
            +
                  #   map.delete("DE") #=> nil
         | 
| 172 | 
            +
                  def delete(key)
         | 
| 173 | 
            +
                    return nil if @root.nil?
         | 
| 174 | 
            +
                    deleted = nil
         | 
| 175 | 
            +
                    splay(key)
         | 
| 176 | 
            +
                    if (key <=> @root.key) == 0 # The key exists
         | 
| 177 | 
            +
                      deleted = @root.value
         | 
| 178 | 
            +
                      if @root.left.nil?
         | 
| 179 | 
            +
                        @root = @root.right
         | 
| 180 | 
            +
                      else
         | 
| 181 | 
            +
                        x = @root.right
         | 
| 182 | 
            +
                        @root = @root.left
         | 
| 183 | 
            +
                        splay(key)
         | 
| 184 | 
            +
                        @root.right = x
         | 
| 185 | 
            +
                      end
         | 
| 186 | 
            +
                    end
         | 
| 187 | 
            +
                    deleted
         | 
| 188 | 
            +
                  end
         | 
| 189 | 
            +
              
         | 
| 190 | 
            +
                  # Iterates over the SplayTreeMap in ascending order. Uses an iterative, not recursive, approach.
         | 
| 191 | 
            +
                  def each
         | 
| 192 | 
            +
                    return nil unless @root
         | 
| 193 | 
            +
                    stack = Stack.new
         | 
| 194 | 
            +
                    cursor = @root
         | 
| 195 | 
            +
                    loop do
         | 
| 196 | 
            +
                      if cursor
         | 
| 197 | 
            +
                        stack.push(cursor)
         | 
| 198 | 
            +
                        cursor = cursor.left
         | 
| 199 | 
            +
                      else
         | 
| 200 | 
            +
                        unless stack.empty?
         | 
| 201 | 
            +
                          cursor = stack.pop
         | 
| 202 | 
            +
                          yield(cursor.key, cursor.value)
         | 
| 203 | 
            +
                          cursor = cursor.right
         | 
| 204 | 
            +
                        else
         | 
| 205 | 
            +
                          break
         | 
| 206 | 
            +
                        end
         | 
| 207 | 
            +
                      end
         | 
| 208 | 
            +
                    end
         | 
| 209 | 
            +
                  end
         | 
| 210 | 
            +
              
         | 
| 211 | 
            +
                  # Moves a key to the root, updating the structure in each step.
         | 
| 212 | 
            +
                  def splay(key)
         | 
| 213 | 
            +
                    l, r = @header, @header
         | 
| 214 | 
            +
                    t = @root
         | 
| 215 | 
            +
                    @header.left, @header.right = nil, nil
         | 
| 216 | 
            +
                
         | 
| 217 | 
            +
                    loop do
         | 
| 218 | 
            +
                      if (key <=> t.key) == -1
         | 
| 219 | 
            +
                        break unless t.left
         | 
| 220 | 
            +
                        if (key <=> t.left.key) == -1
         | 
| 221 | 
            +
                          y = t.left
         | 
| 222 | 
            +
                          t.left = y.right
         | 
| 223 | 
            +
                          y.right = t
         | 
| 224 | 
            +
                          t = y
         | 
| 225 | 
            +
                          break unless t.left
         | 
| 226 | 
            +
                        end
         | 
| 227 | 
            +
                        r.left = t
         | 
| 228 | 
            +
                        r = t
         | 
| 229 | 
            +
                        t = t.left
         | 
| 230 | 
            +
                      elsif (key <=> t.key) == 1
         | 
| 231 | 
            +
                        break unless t.right
         | 
| 232 | 
            +
                        if (key <=> t.right.key) == 1
         | 
| 233 | 
            +
                          y = t.right
         | 
| 234 | 
            +
                          t.right = y.left
         | 
| 235 | 
            +
                          y.left = t
         | 
| 236 | 
            +
                          t = y
         | 
| 237 | 
            +
                          break unless t.right
         | 
| 238 | 
            +
                        end
         | 
| 239 | 
            +
                        l.right = t
         | 
| 240 | 
            +
                        l = t
         | 
| 241 | 
            +
                        t = t.right
         | 
| 242 | 
            +
                      else
         | 
| 243 | 
            +
                        break
         | 
| 244 | 
            +
                	    end
         | 
| 245 | 
            +
                    end
         | 
| 246 | 
            +
                    l.right = t.left
         | 
| 247 | 
            +
                    r.left = t.right
         | 
| 248 | 
            +
                    t.left = @header.right
         | 
| 249 | 
            +
                    t.right = @header.left
         | 
| 250 | 
            +
                    @root = t
         | 
| 251 | 
            +
                  end
         | 
| 252 | 
            +
                  private :splay
         | 
| 253 | 
            +
              
         | 
| 254 | 
            +
                  # Recursively determine height
         | 
| 255 | 
            +
                  def height_recursive(node)
         | 
| 256 | 
            +
                    return 0 if node.nil?
         | 
| 257 | 
            +
                
         | 
| 258 | 
            +
                    left_height   = 1 + height_recursive(node.left)
         | 
| 259 | 
            +
                    right_height  = 1 + height_recursive(node.right)
         | 
| 260 | 
            +
                
         | 
| 261 | 
            +
                    left_height > right_height ? left_height : right_height
         | 
| 262 | 
            +
                  end
         | 
| 263 | 
            +
                  private :height_recursive
         | 
| 264 | 
            +
                end
         | 
| 265 | 
            +
              end
         | 
| 266 | 
            +
             | 
| 267 | 
            +
              begin
         | 
| 268 | 
            +
                require 'CSplayTreeMap'
         | 
| 269 | 
            +
                Containers::SplayTreeMap = Containers::CSplayTreeMap
         | 
| 270 | 
            +
              rescue Object # C Version could not be found, try ruby version
         | 
| 271 | 
            +
                Containers::SplayTreeMap = Containers::RubySplayTreeMap
         | 
| 272 | 
            +
              end
         | 
| 273 | 
            +
            end
         |