note description: "Demo class for binary trees." legal: "See notice at end of class." status: "See notice at end of class." class BINARY_TREE_DEMO inherit TOP_DEMO redefine cycle, fill_menu, execute, make end create make feature {NONE} -- Creation make -- Initialize and execute demonstration. do Precursor driver.new_menu ("%N%N* BINARY TREE DEMO *%N%N[XX] shows current node%N") fill_menu create tree_root.make (0) active := tree_root cycle end feature {NONE} -- Attributes root, left, right, parent, put, child_status, add_left, add_right, remove_left_child, remove_right_child, child_put_left, child_put_right, show, quit: INTEGER -- Command code. tree_root: BINARY_TREE [INTEGER] -- Structure to operate on. active: BINARY_TREE [INTEGER] -- Current position in the structure. feature {NONE} -- Basic operations cycle -- local new_command: INTEGER do from driver.print_menu tree_trace (tree_root, 0) new_command := driver.get_choice until new_command = quit loop execute (new_command) driver.new_line driver.start_result tree_trace (tree_root, 0) driver.end_result new_command := driver.get_choice end driver.exit end tree_trace (t: BINARY_TREE [INTEGER]; i: INTEGER) -- Display `t`, indented by `i` positions. require tree_not_void: t /= Void local j: INTEGER do if attached t.left_child as c then tree_trace (c, i + 3) end from j := 1 until j > i loop driver.putstring (" ") j := j + 1 end; if t = active then driver.putstring ("[") driver.putint (t.item) driver.putstring ("]") else driver.putstring (" ") driver.putint (t.item) driver.putstring (" ") end driver.new_line if attached t.right_child as c then tree_trace (c, i + 3) end end fill_menu -- Fill the menu with the available commands. do driver.add_entry ("AL (Add Left): Add a left child", "Add a sub-tree on the left of the current node") add_left := driver.last_entry driver.add_entry ("AR (Add Right): Add a right child", "Add a sub-tree on the right of the current node") add_right := driver.last_entry driver.add_entry ("CL (Child Left): Change value of left child", "Change item at left child of current node") child_put_left := driver.last_entry driver.add_entry ("CR (Child Right): Change value of right child", "Change item at right child of current node") child_put_right := driver.last_entry driver.add_entry ("PU (PUt): Change value of active node", "Change value of active node") put := driver.last_entry driver.add_entry ("RL (Remove Left): Remove left child", "Remove left child of current node") remove_left_child := driver.last_entry driver.add_entry ("RR (Remove Right): Remove right child", "Remove right child of current node") remove_right_child := driver.last_entry driver.add_entry ("RO (): Go to root", "Go to root node") root := driver.last_entry driver.add_entry ("LE (Left): Go to left child", "Go to left child") left := driver.last_entry driver.add_entry ("RI (Right): Go to right child", "Go to right child") right := driver.last_entry driver.add_entry ("PA (Parent): Go to parent", "Go to parent of current node") parent := driver.last_entry driver.add_entry ("CS (Child Status): Information on current node", "Print information on current node") child_status := driver.last_entry driver.add_entry ("SH (SHow): Show tree", "Display tree contents") show := driver.last_entry driver.add_entry ("QU (QUit)", "Terminate this session") quit := driver.last_entry driver.complete_menu end execute (new_command: INTEGER) -- Execute command corresponding to user's request. local new : like active do --| parse and perform action if new_command = left then if attached active.left_child as c then active := c else driver.signal_error ("Cannot execute: no left child.") end elseif new_command = right then if attached active.right_child as c then active := c else driver.signal_error ("Cannot execute: no right child.") end elseif new_command = root then active := tree_root elseif new_command = parent then if attached active.parent as p then active := p else driver.signal_error ("Cannot execute: no parent.") end elseif new_command = child_status then driver.putstring ("has_right ") driver.putbool (active.has_right) driver.new_line driver.putstring ("has_left ") driver.putbool (active.has_left) driver.new_line driver.putstring ("has_none ") driver.putbool (active.has_none) driver.new_line driver.putstring ("has_both ") driver.putbool (active.has_both) driver.new_line elseif new_command = add_left then create new.make (driver.get_integer ("item")) active.put_left_child (new) elseif new_command = add_right then create new.make (driver.get_integer ("item")) active.put_right_child (new) elseif new_command = put then active.put (driver.get_integer ("item")) elseif new_command = remove_right_child then active.remove_right_child elseif new_command = remove_left_child then active.remove_left_child elseif new_command = child_put_right then if active.has_right then active.child_go_i_th (2) active.child_replace (driver.get_integer ("item")) else driver.signal_error ("Cannot execute: no right child"); end elseif new_command = child_put_left then if active.has_left then active.child_go_i_th (1) active.child_replace (driver.get_integer ("item")) else driver.signal_error ("cannot execute: no left child") end elseif new_command /= show then driver.signal_error ("Unknown command") end end note date: "$Date$" revision: "$Revision$" copyright: "Copyright (c) 1984-2017, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end