A simple multi-tree implementation:
- Use the iterator to easily build a tree,
- It can be output recursively, in the forward or backward order.
- Use stacks for output.
- Tree destruction can only be performed in descending order.
Class Definition:
# Include <iostream> <br/> # include <string> <br/> # include <vector> <br/> # include <stack> <br/> # include <cassert> <br/> using namespace STD; <br/> template <class T> <br/> class htree_node {<br/> Public: <br/> typedef htree_node <t> node_type; <br/> htree_node () <br/>: parent (0), format ("") <br/>{}< br/> htree_node (const T & X) <br/>: name (x), parent (0), format ("") <br/>{}< br/> ~ Htree_node () <br/>{}< br/> T name; <br/> // two spaces by default <br/> STD: string format; <br/> node_type * parent; <br/> STD: vector <node_type *> children; <br/>}; <br/> template <class t, class Container = htree_node <t> <br/> class htree {<br/> protected: <br/> typedef container tree_node; <br/> public: <br/> htree () <br/>: Root (0) <br/> {Init () ;}< br/> htree (tree_node * node) <br/>: Root (node) <br/> {Init () ;}< br/> ~ Htree () {<br/> destroy (Root); <br/>}< br/> // pre_order_iterator <br/> class iterator {<br/> public: <br/> iterator () <br/>: _ node (0) <br/>, skip_current_children _ (false) <br/>{< br/> skip_children (); <br/>}< br/> iterator (tree_node * node) <br/>: _ node (node) <br/>, skip_current_children _ (false) <br/>{< br/> skip_children (); <br/>}< br/> ~ Iterator () <br/>{}< br/> T & operator * () const <br/>{< br/> return _ node-> name; <br/>}< br/> T * operator-> () const <br/> {<br/> return & (_ node-> name ); <br/>}< br/> tree_node * Get () <br/> {<br/> return _ node; <br/>}< br/> // start position <br/> iterator begin () const <br/>{< br/> return iterator (_ node ); <br/>}< br/> // end position const ???? <Br/> iterator end () const <br/>{< br/> return iterator (_ find_end (_ node )); <br/>}</P> <p> tree_node * _ node; <br/> protected: <br/> bool skip_current_children _; <br/> void skip_children () <br/>{< br/> skip_current_children _ = true; <br/>}< br/> tree_node * _ find_end (tree_node * Current) const <br/> {<br/> int Pos = Current-> children. size ()-1; <br/> If (Pos <0) <br/> return (current); <br/> // The iterator returned here will be destructed, temporary object <br/> // start from the last child, <br/> else <br/> _ find_end (current-> Children [POS]); <br/>}< br/>}; <br/> Public: <br/> // note the reference of position transfer <br/> iterator insert (iterator & position, const T & X) <br/>{< br/> tree_node * TMP = new tree_node (x); <br/> position. _ node-> children. push_back (TMP); <br/> TMP-> parent = position. _ node; <br/> return iterator (TMP); <br/>}< br/> // post-order recursive output <br/> void post_recurs_render (tree_node * some, unsigned recurs_level) <br/>{< br/> for (unsigned I = 0; I <some-> children. size (); I ++) <br/> post_recurs_render (some-> Children [I], recurs_level + 1); <br/> for (INT I = 0; I <recurs_level; I ++) <br/> cout <""; <br/> cout <some-> name <Endl; <br/>}< br/> // first-order recursive output <br/> void pre_recurs_render (tree_node * Some, unsigned recurs_level) <br/> {<br/> for (INT I = 0; I <recurs_level; I ++) <br/> cout <""; <br/> cout <some-> name <Endl; <br/> for (unsigned I = 0; I <some-> children. size (); I ++) <br/> pre_recurs_render (some-> Children [I], recurs_level + 1 ); <br/>}</P> <p> // use the stack <br/> // format the output using transform <br/> void recurs_render (tree_node * Some) <br/>{< br/> STD: String temp; <br/> temp = form_stack.top () + some-> Format; <br/> form_stack.push (temp ); </P> <p> cout <temp; <br/> cout <some-> name; <br/> cout <Endl; <br/> for (unsigned I = 0; I <some-> children. size (); I ++) <br/> recurs_render (some-> Children [I]); <br/> form_stack.pop (); <br/>}< br/> tree_node * root; <br/> PRIVATE: <br/> void Init () {<br/> form_stack.push (STD :: string (""); <br/>}; <br/> void destroy (tree_node * Some) <br/>{< br/> # define safe_delete (P) {If (p) {Delete P; P = NULL ;}< br/> // delete in descending order <br/> for (unsigned I = 0; I <some-> children. size (); I ++) <br/> destroy (some-> Children [I]); <br/> safe_delete (some ); <br/>}< br/> STD: Stack <STD: String> form_stack; <br/> };
The following is the test code in the main function:
Int main () <br/>{< br/> // for detecting the memory leaks <br/> int tmpflag = _ crtsetdbgflag (_ crtdbg_report_flag ); <br/> tmpflag | = _ crtdbg_leak_check_df; <br/> _ crtsetdbgflag (tmpflag); <br/> typedef htree_node <string> node_type; <br/> typedef htree <string> tree_type; <br/> node_type * One = new node_type ("one"); </P> <p> tree_type :: iterator ITER (one); <br/> tree_type tr1 (one); <br/> tree_type: iterator two = tr1.insert (ITER, "two "); <br/> tree_type: iterator three = tr1.insert (ITER, "three"); <br/> tr1.insert (two, "apple"); <br/> tr1.insert (two, "banana"); <br/> tr1.insert (two, "Peach"); <br/> tr1.insert (three, "China"); <br/> tr1.insert (three, "England"); </P> <p> // Method 1: <br/> tr1.recurs _ render (tr1.root ); <br/> cout <"--------" <Endl; </P> <p> // Method 2: <br/> tr1.pre _ recurs_render (tr1.root, 1 ); <br/> cout <"--------" <Endl; <br/> // method 3: <br/> tr1.post _ recurs_render (tr1.root, 1 ); <br/> cout <"--------" <Endl; <br/> // test iterator: end () function <br/> cout <(* (ITER. end () <Endl; <br/> return 0; <br/>}
Final output result:
One <br/> two <br/> Apple <br/> banana <br/> peach <br/> three <br/> China <br/> engand <br/> -------- <br/> one <br/> two <br/> Apple <br/> banana <br/> peach <br/> three <br/> China <br/> england <br/> -------- <br/> Apple <br/> banana <br/> peach <br/> two <br/> China <br/> England <br/> three <br/> one <br/> -------- <br/> engand