note description: "Trees where the children of each node are kept in an array" library: "Free implementation of ELKS library" legal: "See notice at end of class." status: "See notice at end of class." names: tree representation: recursive, array access: cursor, membership contents: generic date: "$Date: 2018-12-15 18:01:30 +0000 (Sat, 15 Dec 2018) $" revision: "$Revision: 102607 $" class ARRAYED_TREE [G] inherit CELL [G] undefine copy, is_equal end DYNAMIC_TREE [G] rename empty as al_empty export {NONE} al_empty undefine child_after, readable_child, writable_child, child_off, child_before redefine parent, attach_to_parent, duplicate, extend, duplicate_all, fill_subtree end create make feature {NONE} -- Initialization make (n: INTEGER_32; v: G) -- Create node with item v. -- Allocate space for n children. require valid_number_of_children: n >= 0 do create arrayed_list.make (n) replace (v) ensure node_item: item = v end feature -- Access parent: detachable like Current -- Parent of current node left_sibling: like parent -- Left neighbor if any local p: like parent do p := parent if p /= Void and then position_in_parent > 1 then Result := p.array_item (position_in_parent - 1) end end right_sibling: like parent -- Right neighbor if any local p: like parent do p := parent if p /= Void and then position_in_parent < p.arity then Result := p.array_item (position_in_parent + 1) end end feature -- Element change child_put (v: like item) -- Replace current child item with v. -- Was declared in ARRAYED_TREE as synonym of child_replace. local c: like child do c := child if c /= Void then if object_comparison then c.compare_objects else c.compare_references end; c.replace (v) end end child_replace (v: like item) -- Replace current child item with v. -- Was declared in ARRAYED_TREE as synonym of child_put. local c: like child do c := child if c /= Void then if object_comparison then c.compare_objects else c.compare_references end; c.replace (v) end end replace_child (n: like child) -- Make n the node's current child. do if object_comparison then n.compare_objects else n.compare_references end if child_off then al_extend (n) else al_replace (n) end; n.attach_to_parent (Current) ensure then child_replaced: n.parent = Current end child_extend (v: like item) -- Add v at end. -- Do not move child cursor. local n: like parent do n := new_cell (v) if object_comparison then n.compare_objects else n.compare_references end al_extend (n) end child_put_left (v: like item) -- Add v to the left of cursor position. -- Do not move child cursor. local n: like parent do n := new_cell (v) if object_comparison then n.compare_objects else n.compare_references end al_put_left (n) end child_put_right (v: like item) -- Add v to the right of cursor position. -- Do not move child cursor. local n: like parent do n := new_cell (v) if object_comparison then n.compare_objects else n.compare_references end al_put_right (n) end put_child_left (n: like child) -- Add n to the left of cursor position. -- Do not move cursor. do if object_comparison then n.compare_objects else n.compare_references end al_put_left (n); n.attach_to_parent (Current) end put_child_right (n: like child) -- Add n to the right of the cursor position. -- Do not move cursor. do if object_comparison then n.compare_objects else n.compare_references end al_put_right (n); n.attach_to_parent (Current) end put_child (n: like child) -- Add n to the list of children. -- Do not move child cursor. do if object_comparison then n.compare_objects else n.compare_references end al_extend (n); n.attach_to_parent (Current) end merge_tree_before (other: like Current) -- Merge children of other into current structure -- before cursor position. Do not move cursor. -- Make other a leaf. local l_list: ARRAYED_LIST [like other] do attach (other) create l_list.make (1); l_list.extend (other) al_merge_left (l_list) end merge_tree_after (other: like Current) -- Merge children of other into current structure -- after cursor position. Do not move cursor. -- Make other a leaf. local l_list: ARRAYED_LIST [like other] do attach (other) create l_list.make (1); l_list.extend (other) al_merge_left (l_list) end feature -- Removal remove_child -- Remove child at cursor position. -- Move cursor to the next sibling, or after if none. local c: like child do c := child if c /= Void then c.attach_to_parent (Void) end al_remove end remove_left_child -- Remove item to the left of cursor position. -- Do not move cursor. do child_back remove_child end remove_right_child -- Remove item to the right of cursor position. -- Do not move cursor. do child_forth remove_child child_back end forget_left -- Forget all left siblings. local i: INTEGER_32 old_idx: INTEGER_32 p: like parent do p := parent if p /= Void and then position_in_parent < p.arity then old_idx := p.child_index from i := 1 until i = position_in_parent loop p.child_go_i_th (i); p.remove_child i := i + 1 end; p.child_go_i_th (old_idx) end end forget_right -- Forget all right siblings. local i: INTEGER_32 old_idx: INTEGER_32 p: like parent do p := parent if p /= Void and then position_in_parent < p.arity then old_idx := p.child_index from i := position_in_parent + 1 until i > p.arity loop p.child_go_i_th (i); p.remove_child i := i + 1 end; p.child_go_i_th (old_idx) end end feature -- Duplication duplicate (n: INTEGER_32): like Current obsolete "Create and initialize a new tree explicitly. [2018-11-30]" -- Copy of sub-tree beginning at cursor position and -- having min (n, arity - child_index + 1) -- children. local counter: INTEGER_32 pos: CURSOR c: like child do from Result := new_node pos := child_cursor; Result.child_start until child_after or else (counter = n) loop c := child if c /= Void then Result.replace_child (c.duplicate_all) end; Result.child_forth child_forth counter := counter + 1 end child_go_to (pos) end feature -- Inapplicable extend (v: G) -- Add v as new child. do end set_child (n: like parent) -- Set child to n. do end feature {ARRAYED_TREE} -- Implementation new_node: like Current obsolete "Create and initialize a new tree explicitly. [2018-11-30]" -- A newly created instance of the same type, -- with the same arity and node value. -- This feature may be redefined in descendants so as to -- produce an adequately allocated and initialized object. do create Result.make (arity, item) end duplicate_all: like Current obsolete "Create and initialize a new tree explicitly. [2018-11-30]" -- Copy of sub-tree including all children local pos: CURSOR c: like child do from Result := new_node pos := child_cursor; Result.child_start child_start until child_off loop c := child if c /= Void then Result.replace_child (c.duplicate_all) end; Result.child_forth child_forth end child_go_to (pos) end fill_subtree (other: TREE [G]) obsolete "Fill subtree explicitly. [2018-11-30]" -- Fill children with children of other local temp: like parent c: detachable TREE [G] do from other.child_start child_start until child_after loop c := other.child if c /= Void then create temp.make (other.arity, other.child_item); temp.fill_subtree (c) replace_child (temp) end child_forth; other.child_forth end end attach_to_parent (n: like parent) -- Make n parent of current node; do parent := n end clone_node (n: like Current): like Current -- Clone node n. do create Result.make (n.arity, n.item); Result.copy_node (n) end copy_node (n: like Current) -- Copy content of n except tree data into Current. local l_arrayed_list: like arrayed_list do l_arrayed_list := arrayed_list standard_copy (n) arrayed_list := l_arrayed_list parent := Void end feature {NONE} -- Implementation arrayed_list: ARRAYED_LIST [like Current] -- arrayed list of arrayed_tree. new_tree: like Current obsolete "Create and initialize a new tree explicitly. [2018-11-30]" -- A newly created instance of the same type. do create Result.make (0, item) end new_cell (v: like item): like Current -- New node with value v and no children. do create Result.make (0, v); Result.attach_to_parent (Current) end position_in_parent: INTEGER_32 -- Position of current node in parent local p: like parent do p := parent if p /= Void then Result := p.index_of (Current, 1) end end attach (other: like Current) -- Attach all children of other to current node. -- Put other in mode off. local c: like child do from other.child_start until other.child_off loop c := other.child; other.child_forth if c /= Void then c.attach_to_parent (Current) end end end do_all_internal (an_agent: PROCEDURE [G]; a_tree_node: like Current) -- Apply action to every child. require non_void_agent: an_agent /= Void do an_agent (a_tree_node.item) from a_tree_node.child_start until a_tree_node.child_off loop do_all_internal (an_agent, a_tree_node.child); a_tree_node.child_forth end end feature -- Access: children child: attached like parent -- Current child node do Result := arrayed_list.item end array_item (n: INTEGER_32): like Current do Result := arrayed_list.i_th (n) end last_child: like first_child -- Right most child do Result := arrayed_list.last end first_child: like parent -- Leftmost child do Result := arrayed_list.first end search_child (v: like Current) do arrayed_list.search (v) end readable_child: BOOLEAN -- Is there a current child to be read? do Result := arrayed_list.readable end writable_child: BOOLEAN -- Is there a current child that may be modified? do Result := arrayed_list.writable end arity: INTEGER_32 -- Number of children do Result := arrayed_list.count end child_start -- Move cursor to first child. do arrayed_list.start end child_finish -- Move cursor to last child. do arrayed_list.finish end child_forth -- Move cursor to next child. do arrayed_list.forth end child_back -- Move cursor to previous child. do arrayed_list.back end child_go_i_th (i: INTEGER_32) -- Move cursor to i-th child. do arrayed_list.go_i_th (i) end child_index: INTEGER_32 -- Index of current child do Result := arrayed_list.index end child_off: BOOLEAN -- Is there no current child? do Result := arrayed_list.off end child_after: BOOLEAN -- Is there no valid child position to the right of cursor? do Result := arrayed_list.after end child_before: BOOLEAN -- Is there no valid child position to the left of cursor? do Result := arrayed_list.before end child_cursor: CURSOR -- Current cursor position do Result := arrayed_list.cursor end child_go_to (p: CURSOR) -- Move cursor to position p. do arrayed_list.go_to (p) end index_of (v: like Current; i: INTEGER_32): INTEGER_32 do Result := arrayed_list.index_of (v, i) end prune (n: like child) -- Remove n from the children. do arrayed_list.prune (n) end wipe_out -- Remove all children. do arrayed_list.wipe_out end child_move (i: INTEGER_32) do arrayed_list.move (i) end do_all (an_agent: PROCEDURE [G]) -- Apply an_agent to every child nodes in the tree. do do_all_internal (an_agent, Current) end feature {NONE} -- private access arrayed_list al_extend (v: like Current) do arrayed_list.extend (v) end al_duplicate (n: INTEGER_32): ARRAYED_LIST [like Current] obsolete "[ Create a new container explicitly using `make_from_iterable` if available. Otherwise, replace a call to the feature with code that creates and initializes container. [2018-11-30] ]" do Result := arrayed_list.duplicate (n) end al_remove do arrayed_list.remove end al_remove_left do arrayed_list.remove_left end al_remove_right do arrayed_list.remove_right end al_put_left (v: like Current) do arrayed_list.put_left (v) end al_put_right (v: like Current) do arrayed_list.put_right (v) end al_merge_left (v: ARRAYED_LIST [like Current]) do arrayed_list.merge_left (v) end al_merge_right (v: ARRAYED_LIST [like Current]) do arrayed_list.merge_right (v) end al_object_comparison: BOOLEAN do Result := arrayed_list.object_comparison end al_full: BOOLEAN do Result := arrayed_list.full end al_extendible: BOOLEAN do Result := arrayed_list.extendible end al_put (v: like Current) do arrayed_list.put (v) end al_replace (v: like Current) do arrayed_list.replace (v) end al_fill (other: CONTAINER [like Current]) do arrayed_list.fill (other) end al_lin_rep: LINEAR [like Current] do Result := arrayed_list.linear_representation end al_has (v: like Current): BOOLEAN do Result := arrayed_list.has (v) end note ca_ignore: "CA033", "CA033: very large class" copyright: "Copyright (c) 1984-2018, 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 -- class ARRAYED_TREE
Generated by ISE EiffelStudio