Guest User

Untitled

a guest
Jul 23rd, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.62 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2. #
  3. # Fri Feb 11 13:36:25 EST 2011
  4. #
  5. # a learning example of a Left-Leaning Red-Black Tree, in ruby
  6. #
  7. # you can import this as a library,
  8. # irb -r ./rbtree.rb
  9. # irb 0:01> run(10000)
  10. #
  11. # or
  12. # run it as a script
  13. # $> ruby rbtree.rb [sample_size]
  14. # which will output the results of a descending trail of sample_size/2
  15. # default sample size is 10,000
  16. #
  17.  
  18. class RBTree
  19. include Comparable
  20. RED = true
  21. BLACK = false
  22. attr_accessor :root
  23.  
  24. def initialize
  25. self.root = RBNode.new()
  26. end
  27.  
  28. def insert(key,val)
  29. self.root = insert_local(self.root, key, val)
  30. self.root.color = BLACK
  31. end
  32.  
  33. def insert_local(node, key, val)
  34. if node.nil?
  35. return RBNode.new(key, val)
  36. end
  37. if node.key.nil?
  38. return RBNode.new(key, val)
  39. end
  40.  
  41. # Uncomment this, for a 2-3-4 node tree implementation
  42. # and comment about below
  43. # if (isRed(node.right) && isRed(node.left))
  44. # flipColors(node)
  45. # end
  46.  
  47. if (key == node.key)
  48. #dup
  49. elsif (key > node.key)
  50. node.right = insert_local(node.right, key, val)
  51. else
  52. node.left = insert_local(node.left, key, val)
  53. end
  54.  
  55. if (isRed(node.right) && !isRed(node.left))
  56. node = rotateLeft(node)
  57. end
  58. if (isRed(node.left) && isRed(node.left.left))
  59. node = rotateRight(node)
  60. end
  61.  
  62. # with this test here, this acts as a 2-3 node tree
  63. # which i've seen a decent performance benefit of,
  64. # over the 2-3-4 node tree
  65. if (isRed(node.right) && isRed(node.left))
  66. flipColors(node)
  67. end
  68.  
  69. return node
  70. end
  71. private :insert_local
  72.  
  73. def search(key,val=nil)
  74. node = self.root
  75.  
  76. while true
  77. if (key == node.key)
  78. return node
  79. elsif (key < node.key)
  80. node = node.left
  81. elsif (key > node.key)
  82. node = node.right
  83. end
  84.  
  85. # Nothing has been found
  86. if node.nil?
  87. break
  88. end
  89. end
  90.  
  91. return nil
  92. end
  93.  
  94. def delete
  95. end
  96.  
  97. def bottomLeft
  98. node_send = self.root
  99. counter = 0
  100. while true
  101. node_recv = bottomLeft_local(node_send)
  102. if node_send == node_recv
  103. return [counter, node_recv]
  104. else
  105. counter += 1
  106. node_send = node_recv
  107. end
  108. end
  109. end
  110.  
  111. def bottomLeft_local(node)
  112. if node.left.nil?
  113. return node
  114. else
  115. return node.left
  116. end
  117. end
  118. private :bottomLeft_local
  119.  
  120. def bottomRight
  121. node_send = self.root
  122. counter = 0
  123. while true
  124. node_recv = bottomRight_local(node_send)
  125. if node_send == node_recv
  126. return [counter, node_recv]
  127. else
  128. counter += 1
  129. node_send = node_recv
  130. end
  131. end
  132. end
  133.  
  134. def bottomRight_local(node)
  135. if node.right.nil?
  136. return node
  137. else
  138. return node.right
  139. end
  140. end
  141. private :bottomRight_local
  142.  
  143. def rotateLeft(node)
  144. x = node.right
  145. node.right = x.left
  146. x.left = node
  147. x.color = node.color
  148. node.color = RED
  149. return x
  150. end
  151.  
  152. def rotateRight(node)
  153. x = node.left
  154. node.left = x.right
  155. x.right = node
  156. x.color = node.color
  157. node.color = RED
  158. return x
  159. end
  160.  
  161. def isRed(node)
  162. if node.nil?
  163. return false
  164. else
  165. return node.color
  166. end
  167. end
  168.  
  169. def flipColors(node)
  170. node.color = !node.color
  171. node.right.color = !node.right.color
  172. node.left.color = !node.left.color
  173. end
  174.  
  175. def inspect
  176. "#<%s:0x%p root=%s>" % [self.class.name, self.object_id, self.root]
  177. end
  178.  
  179. class RBNode
  180. attr_accessor :key, :val, :color, :left, :right
  181. def initialize(key = nil, val = nil)
  182. self.key = key
  183. self.val = val
  184. self.color = RED
  185. end
  186. def <=>(another)
  187. self.key <=> another.key
  188. end
  189. def inspect
  190. "#<%s:0x%p key=\"%s\" val=\"%s\" color=\"%s\">" % [self.class.name, self.object_id, self.key, self.val, self.color ? "RED" : "BLACK"]
  191. end
  192. end
  193. end
  194.  
  195. def uniq_rand_set(f = 100)
  196. (0..f).map {|i| i }.shuffle
  197. end
  198.  
  199. def uniq_rand(f = 100)
  200. if @rand_set.nil?
  201. @rand_set = uniq_rand_set(f)
  202. end
  203. return @rand_set.pop
  204. end
  205.  
  206. def run(sample_size = 10000)
  207. tree = RBTree.new
  208. count = sample_size
  209.  
  210. while count > 0
  211. tree.insert(uniq_rand(sample_size), nil)
  212. count -= 1
  213. end
  214.  
  215. @rand_set = nil
  216. return tree
  217. end
  218.  
  219. def run_loop(start_size)
  220. @results = []
  221. local_size = start_size
  222.  
  223. while true
  224. time_start = Time.now.to_f
  225. t = run(local_size)
  226. time_stop = Time.now.to_f
  227. diff = time_stop - time_start
  228.  
  229.  
  230. @results << [local_size, diff, t.bottomLeft[0], t.bottomRight[0]]
  231. local_size = (local_size.to_f/2).to_i
  232.  
  233. # allow a bit of garbage collection
  234. t = diff = time_stop = time_start = nil
  235.  
  236. if local_size <= 1
  237. break
  238. end
  239.  
  240. end
  241.  
  242. return @results
  243. end
  244.  
  245. times=10000
  246. if ARGV[0]
  247. times = ARGV[0].to_i
  248. end
  249. p run_loop(times)
Add Comment
Please, Sign In to add comment