ruby - Stoping condition of recursive method doesn't work at the right time -


a peculiar problem ocurring me. i'm coding binary search tree methods:

class binarysearchtree   class node     attr_accessor :value, :height     attr_accessor :left, :right      def initialize(value, height)       @value = value       @height = height     end   end   attr_accessor :root  def initialize   @root = node.new(nil, 0) end  def insert(value)   node = @root   loop     case value <=> node.value     when -1       if node.left.nil?         node.left = node.new(value, node.height + 1)         break       else         node = node.left       end     when 1       if node.right.nil?         node.right = node.new(value, node.height + 1)         break       else         node = node.right       end     else       node.value = value       break     end   end end  def delete(value, node = @root)   return if node.nil?   if value == node.value     node = delete_node(node)   elsif value < node.value     node.left = delete(value, node.left)   elsif     node.right = delete(value, node.right)   end   node end  def delete_node(node)   if node.left.nil? && node.right.nil?     node = nil   elsif node.left.nil? || node.right.nil?     if node.left.nil?       node = node.right       update_subtrees_height(node, -1, {left: false, right: true})     else       node = node.right end       update_subtrees_height(node, -1, {left: true, right: false})   else     #todo   end   node end  def update_subtrees_height(node, value, options = {left: true, right: true})   return if node.nil?   node.height = node.height + value   update_subtrees_height(node.left, value, options) if options[:left]   update_subtrees_height(node.right, value, options) if options[:right] end  # debug def print_tree(node = @root)   return if node.nil?   puts "#{node.left.nil? ? 'null' : node.left.value} - #{node.nil? ? 'null' : node.value}(h#{node.height}) - #{node.right.nil? ? 'null' : node.right.value}"   print_tree(node.left)   print_tree(node.right) end end 

the problem occurs in update_subtrees_height. consider test:

btree = binarysearchtree.new  [8,7,9,10].each |v|   btree.insert(v) end  btree.print_tree btree.root btree.root = btree.delete(9) btree.print_tree btree.root 

step step, test does:

1) buil tree , print (the output print_tree method):

7 - 8(h0) - 9 null - 7(h1) - null null - 9(h1) - 10 null - 10(h2) - null 

that represents following tree:

   8     # height 0   / \  7   9   # height 1       \       10 # height 2 

2) delete 9 tree , print again:

7 - 8(h0) - 10 null - 7(h1) - null null - 10(h0) - null 

as showed in output, height of child 10 (represented h in output) 0, when should 1. hapens why when call recursive method update_subtrees_height, it's called 2 times before stop. removing 9 replace right child, 10, , call update_subtrees_height passing node 10 decrease height.

calling update method, i've stoping condition return if node.nil?. node 10, doesn't stop @ first iteration, decreaing height 1 (the desired result) , call method recursivly, passing node.right. node.right nil, method doesn't stop @ next iteration (!), decreasing height of node 10 again (to 0 time, output had). @ third iteration, method stop.

someone have idea why third iteration happens?

there error in delete_node method:

def delete_node(node)   if node.left.nil? && node.right.nil?     node = nil   elsif node.left.nil? || node.right.nil?     if node.left.nil?       node = node.right       update_subtrees_height(node, -1, {left: false, right: true})     else       node = node.right end  #                     ^^^       update_subtrees_height(node, -1, {left: true, right: false})   else     #todo   end   node end 

fix following , work!

def delete_node(node)   if node.left.nil? && node.right.nil?     node = nil   elsif node.left.nil? || node.right.nil?     if node.left.nil?       node = node.right       update_subtrees_height(node, -1, {left: false, right: true})     else       node = node.right       update_subtrees_height(node, -1, {left: true, right: false})     end   else     #todo   end   node end 

Comments

Popular posts from this blog

javascript - How to get current YouTube IDs via iMacros? -

c# - Maintaining a program folder in program files out of date? -

emulation - Android map show my location didn't work -