这里用C++实现了一个一般树,也就是那种通用型的树,例如文件系统所用的树。除了一些树的基本操作外,还支持了节点和数据项的迭代器。
实现:
#ifndef GENERAL_TREE_H
#define GENERAL_TREE_H
#include < stdlib.h >
#include < string >
template < typename Object >
struct TreeNode
{
Object element;
TreeNode * parent;
TreeNode * firstChild;
TreeNode * nextSibling;
};
template < class T >
class GeneralIterator
{
public :
virtual T * Next() = 0 ;
virtual void Reset() = 0 ;
};
template < typename Object >
class GeneralTree
{
public :
/* * Constructor * */
GeneralTree();
GeneralTree( const Object & rootElement);
~ GeneralTree();
/* * Get node operations * */
const TreeNode < Object >* GetRoot() const ;
TreeNode < Object >* GetRoot();
const TreeNode < Object >* GetParent( const TreeNode < Object >* v) const ;
/* * Iterators * */
GeneralIterator < Object >* ElementsIterator();
GeneralIterator < TreeNode < Object > >* NodesIterator();
/* * Check the node type * */
bool IsInternal( const TreeNode < Object >* v) const ;
bool IsExternal( const TreeNode < Object >* v) const ;
bool IsRoot( const TreeNode < Object >* v) const ;
/* * Get node count * */
int Size() const ;
/* * Elements operations * */
void SwapElement(TreeNode < Object >* v, TreeNode < Object >* w);
void SetElement(TreeNode < Object >* v, const Object & element);
/* * Node operations * */
TreeNode < Object >* Insert(TreeNode < Object >* parent, const Object & element);
TreeNode < Object >* InsertAfter(TreeNode < Object >* previousSibling,
const Object & element);
void Remove(TreeNode < Object >* v);
void Remove( const Object & element);
TreeNode < Object >* Find( const Object & element);
int GetHeight( const TreeNode < Object >* v) const ;
int GetDepth( const TreeNode < Object >* v) const ;
/* * traversal * */
// param is used to pass in parameters and store results
// the boolean returned value indicates if the traversal is done
typedef bool ( * Action)(TreeNode < Object >* v, void * param);
bool PreorderTraversal(Action action,
void * param = NULL, TreeNode < Object >* pNode = NULL);
bool PostorderTraversal(Action action,
void * param = NULL, TreeNode < Object >* pNode = NULL);
private :
TreeNode < Object >* _root;
int _count;
};
template < typename Object >
TreeNode < Object >* CreateEmptyNode( const Object * pElement)
{
TreeNode < Object >* pNode = new TreeNode < Object > ();
if (pElement != NULL) pNode -> element = * pElement;
pNode -> firstChild = NULL;
pNode -> parent = NULL;
pNode -> nextSibling = NULL;
return pNode;
}
template < typename Object >
GeneralTree < Object > ::GeneralTree()
{
this -> _root = CreateEmptyNode < Object > (NULL);
this -> _count = 1 ;
}
template < typename Object >
GeneralTree < Object > ::GeneralTree( const Object & rootElement)
{
this -> _root = CreateEmptyNode < Object > ( & rootElement);
this -> _count = 1 ;
}
template < typename Object >
GeneralTree < Object > :: ~ GeneralTree()
{
this -> Remove( this -> _root);
}
template < typename Object >
inline const TreeNode < Object >* GeneralTree < Object > ::GetRoot() const
{
return this -> _root;
}
template < typename Object >
inline TreeNode < Object >* GeneralTree < Object > ::GetRoot()
{
return this -> _root;
}
template < typename Object >
inline const TreeNode < Object >* GeneralTree < Object > ::GetParent( const TreeNode < Object >* v) const
{
return v -> parent;
}
template < typename Object >
class ElementsIterator : public GeneralIterator < Object >
{
public :
ElementsIterator(GeneralTree < Object >* tree)
{
_current = - 1 ;
_count = tree -> Size();
_elements = new Object * [_count];
this -> FillPointers(tree);
_current = - 1 ;
}
~ ElementsIterator()
{
delete _elements;
}
Object * Next()
{
++ _current;
if (_current < _count)
return _elements[_current];
else
return NULL;
}
void Reset()
{
_current = - 1 ;
}
private :
Object ** _elements;
int _current;
int _count;
void FillPointers(GeneralTree < Object >* tree);
// friend functions
template < typename T >
friend bool AddPointer(TreeNode < T >* v, void * param);
};
template < typename T >
bool AddPointer(TreeNode < T >* v, void * param)
{
ElementsIterator < T >* itr = (ElementsIterator < T >* )param;
++ (itr -> _current);
(itr -> _elements)[itr -> _current] = & (v -> element);
return false ;
}
template < typename Object >
void ElementsIterator < Object > ::FillPointers(GeneralTree < Object >* tree)
{
tree -> PreorderTraversal(AddPointer, this );
}
template < typename Object >
GeneralIterator < Object >* GetElementsIterator(GeneralTree < Object >* tree)
{
return new ElementsIterator < Object > (tree);
}
template < typename Object >
GeneralIterator < Object >* GeneralTree < Object > ::ElementsIterator()
{
return GetElementsIterator < Object > ( this );
}
template < typename Object >
class NodesIterator : public GeneralIterator < TreeNode < Object > >
{
public :
NodesIterator(GeneralTree < Object >* tree)
{
_current = - 1 ;
_count = tree -> Size();
_elements = new TreeNode < Object >* [_count];
this -> FillPointers(tree);
_current = - 1 ;
}
~ NodesIterator()
{
delete _elements;
}
TreeNode < Object >* Next()
{
++ _current;
if (_current < _count)
return _elements[_current];
else
return NULL;
}
void Reset()
{
_current = - 1 ;
}
private :
TreeNode < Object >** _elements;
int _current;
int _count;
void FillPointers(GeneralTree < Object >* tree);
// friend functions
template < typename T >
friend bool AddNodePointer(TreeNode < T >* v, void * param);
};
template < typename T >
bool AddNodePointer(TreeNode < T >* v, void * param)
{
NodesIterator < T >* itr = (NodesIterator < T >* )param;
++ (itr -> _current);
(itr -> _elements)[itr -> _current] = v;
return false ;
}
template < typename Object >
void NodesIterator < Object > ::FillPointers(GeneralTree < Object >* tree)
{
tree -> PreorderTraversal(AddNodePointer, this );
}
template < typename Object >
GeneralIterator < TreeNode < Object > >* GetNodesIterator(GeneralTree < Object >* tree)
{
return new NodesIterator < Object > (tree);
}
template < typename Object >
GeneralIterator < TreeNode < Object > >* GeneralTree < Object > ::NodesIterator()
{
return GetNodesIterator < Object > ( this );
}
template < typename Object >
inline bool GeneralTree < Object > ::IsInternal( const TreeNode < Object >* v) const
{
return v -> firstChild != NULL;
}
template < typename Object >
inline bool GeneralTree < Object > ::IsExternal( const TreeNode < Object >* v) const
{
return v -> firstChild == NULL;
}
template < typename Object >
inline bool GeneralTree < Object > ::IsRoot( const TreeNode < Object >* v) const
{
return v -> parent == NULL;
}
template < typename Object >
inline int GeneralTree < Object > ::Size() const
{
return this -> _count;
}
template < typename Object >
void GeneralTree < Object > ::SwapElement(TreeNode < Object >* v, TreeNode < Object >* w)
{
Object tem = v -> element;
v -> element = w -> element;
w -> element = tem;
}
template < typename Object >
void GeneralTree < Object > ::SetElement(TreeNode < Object >* v, const Object & element)
{
v -> element = element;
}
template < typename Object >
TreeNode < Object >* GeneralTree < Object > ::Insert(TreeNode < Object >* parent, const Object & element)
{
// Create the new node
TreeNode < Object >* pNewNode = new TreeNode < Object > ();
pNewNode -> element = element;
pNewNode -> parent = parent;
pNewNode -> firstChild = NULL;
pNewNode -> nextSibling = NULL;
// Insert the new node
if (parent -> firstChild == NULL)
{
parent -> firstChild = pNewNode;
}
else
{
TreeNode < Object >* pChild = parent -> firstChild;
while (pChild -> nextSibling != NULL) pChild = pChild -> nextSibling;
pChild -> nextSibling = pNewNode;
}
// increment the count
++ this -> _count;
return pNewNode;
}
template < typename Object >
TreeNode < Object >* GeneralTree < Object > ::InsertAfter(TreeNode < Object >* previousSibling,
const Object & element)
{
// Create the new node
TreeNode < Object >* pNewNode = new TreeNode < Object > ();
pNewNode -> element = element;
pNewNode -> parent = previousSibling -> parent;
pNewNode -> firstChild = NULL;
// Connect new node with its previous node
pNewNode -> nextSibling = previousSibling -> nextSibling;
previousSibling -> nextSibling = pNewNode;
// Increment the count
++ this -> _count;
return pNewNode;
}
template < typename Object >
bool FreeNode(TreeNode < Object >* v, void * param)
{
int * size = ( int * )param;
-- ( * size);
delete v;
return false ;
}
template < typename Object >
void GeneralTree < Object > ::Remove(TreeNode < Object >* v)
{
if (v -> parent != NULL)
{
// find the previous sibling
TreeNode < Object >* pChild = (v -> parent) -> firstChild;
if (pChild == v)
v -> parent -> firstChild = NULL;
else
{
while (pChild -> nextSibling != v) pChild = pChild -> nextSibling;
// adjust the tree structure
pChild -> nextSibling = v -> nextSibling;
}
// free all the children and itself
}
this -> PostorderTraversal(FreeNode, & ( this -> _count),v);
}
template < typename Object >
void GeneralTree < Object > ::Remove( const Object & element)
{
TreeNode < Object >* pRemovedNode = Find(element);
this -> Remove(pRemovedNode);
}
template < typename Object >
struct TestParam
{
Object * pElement;
TreeNode < Object >* pNode;
};
template < typename Object >
bool TestElement(TreeNode < Object >* v, void * param)
{
// the param is an array,
// in which the first element stores the pointer to the element
// and the second element will store the pointer to the found node
TestParam < Object >* pTestParam = (TestParam < Object >* )param;
Object * pElement = pTestParam -> pElement;
if (v -> element == * pElement)
{
pTestParam -> pNode = v; // set the found node
return true ; // it is done.
}
else
return false ;
}
template < typename Object >
TreeNode < Object >* GeneralTree < Object > ::Find( const Object & element)
{
Object findingElement = element;
TestParam < Object > testParam;
testParam.pElement = & findingElement;
this -> PreorderTraversal(TestElement, & testParam);
return testParam.pNode;
}
template < typename Object >
int GeneralTree < Object > ::GetHeight( const TreeNode < Object >* v) const
{
if ( this -> IsExternal(v))
return 0 ;
else
{
int maxChildHeight = 0 ;
TreeNode < Object > pChild = v -> firstChild;
while (pChild != NULL)
{
int childHeight = this -> GetHeight(pChild);
if (childHeight > maxChildHeight)
maxChildHeight = childHeight;
}
return maxChildHeight + 1 ;
}
}
template < typename Object >
int GeneralTree < Object > ::GetDepth( const TreeNode < Object >* v) const
{
if ( this -> IsRoot(v))
return 0 ;
else
return 1 + this -> GetDepth(v -> parent);
}
template < typename Object >
bool GeneralTree < Object > ::PreorderTraversal(Action action,
void * param, TreeNode < Object >* pNode)
{
if (pNode == NULL) pNode = this -> _root;
// visit the node
bool isDone = action(pNode, param);
if (isDone == false )
{
// traverse the children
TreeNode < Object >* pChild = pNode -> firstChild;
while (pChild != NULL)
{
bool isDone = this -> PreorderTraversal(action,
param, pChild);
if (isDone)
break ;
else
pChild = pChild -> nextSibling;
}
}
return isDone;
}
template < typename Object >
bool GeneralTree < Object > ::PostorderTraversal(Action action,
void * param, TreeNode < Object >* pNode)
{
if (pNode == NULL) pNode = this -> _root;
// traverse the children
TreeNode < Object >* pChild = pNode -> firstChild;
while (pChild != NULL)
{
bool isChildDone = this -> PostorderTraversal(action, param, pChild);
if (isChildDone)
return true ;
else
pChild = pChild -> nextSibling;
}
// visit the element
return action(pNode, param);
}
#endif
#define GENERAL_TREE_H
#include < stdlib.h >
#include < string >
template < typename Object >
struct TreeNode
{
Object element;
TreeNode * parent;
TreeNode * firstChild;
TreeNode * nextSibling;
};
template < class T >
class GeneralIterator
{
public :
virtual T * Next() = 0 ;
virtual void Reset() = 0 ;
};
template < typename Object >
class GeneralTree
{
public :
/* * Constructor * */
GeneralTree();
GeneralTree( const Object & rootElement);
~ GeneralTree();
/* * Get node operations * */
const TreeNode < Object >* GetRoot() const ;
TreeNode < Object >* GetRoot();
const TreeNode < Object >* GetParent( const TreeNode < Object >* v) const ;
/* * Iterators * */
GeneralIterator < Object >* ElementsIterator();
GeneralIterator < TreeNode < Object > >* NodesIterator();
/* * Check the node type * */
bool IsInternal( const TreeNode < Object >* v) const ;
bool IsExternal( const TreeNode < Object >* v) const ;
bool IsRoot( const TreeNode < Object >* v) const ;
/* * Get node count * */
int Size() const ;
/* * Elements operations * */
void SwapElement(TreeNode < Object >* v, TreeNode < Object >* w);
void SetElement(TreeNode < Object >* v, const Object & element);
/* * Node operations * */
TreeNode < Object >* Insert(TreeNode < Object >* parent, const Object & element);
TreeNode < Object >* InsertAfter(TreeNode < Object >* previousSibling,
const Object & element);
void Remove(TreeNode < Object >* v);
void Remove( const Object & element);
TreeNode < Object >* Find( const Object & element);
int GetHeight( const TreeNode < Object >* v) const ;
int GetDepth( const TreeNode < Object >* v) const ;
/* * traversal * */
// param is used to pass in parameters and store results
// the boolean returned value indicates if the traversal is done
typedef bool ( * Action)(TreeNode < Object >* v, void * param);
bool PreorderTraversal(Action action,
void * param = NULL, TreeNode < Object >* pNode = NULL);
bool PostorderTraversal(Action action,
void * param = NULL, TreeNode < Object >* pNode = NULL);
private :
TreeNode < Object >* _root;
int _count;
};
template < typename Object >
TreeNode < Object >* CreateEmptyNode( const Object * pElement)
{
TreeNode < Object >* pNode = new TreeNode < Object > ();
if (pElement != NULL) pNode -> element = * pElement;
pNode -> firstChild = NULL;
pNode -> parent = NULL;
pNode -> nextSibling = NULL;
return pNode;
}
template < typename Object >
GeneralTree < Object > ::GeneralTree()
{
this -> _root = CreateEmptyNode < Object > (NULL);
this -> _count = 1 ;
}
template < typename Object >
GeneralTree < Object > ::GeneralTree( const Object & rootElement)
{
this -> _root = CreateEmptyNode < Object > ( & rootElement);
this -> _count = 1 ;
}
template < typename Object >
GeneralTree < Object > :: ~ GeneralTree()
{
this -> Remove( this -> _root);
}
template < typename Object >
inline const TreeNode < Object >* GeneralTree < Object > ::GetRoot() const
{
return this -> _root;
}
template < typename Object >
inline TreeNode < Object >* GeneralTree < Object > ::GetRoot()
{
return this -> _root;
}
template < typename Object >
inline const TreeNode < Object >* GeneralTree < Object > ::GetParent( const TreeNode < Object >* v) const
{
return v -> parent;
}
template < typename Object >
class ElementsIterator : public GeneralIterator < Object >
{
public :
ElementsIterator(GeneralTree < Object >* tree)
{
_current = - 1 ;
_count = tree -> Size();
_elements = new Object * [_count];
this -> FillPointers(tree);
_current = - 1 ;
}
~ ElementsIterator()
{
delete _elements;
}
Object * Next()
{
++ _current;
if (_current < _count)
return _elements[_current];
else
return NULL;
}
void Reset()
{
_current = - 1 ;
}
private :
Object ** _elements;
int _current;
int _count;
void FillPointers(GeneralTree < Object >* tree);
// friend functions
template < typename T >
friend bool AddPointer(TreeNode < T >* v, void * param);
};
template < typename T >
bool AddPointer(TreeNode < T >* v, void * param)
{
ElementsIterator < T >* itr = (ElementsIterator < T >* )param;
++ (itr -> _current);
(itr -> _elements)[itr -> _current] = & (v -> element);
return false ;
}
template < typename Object >
void ElementsIterator < Object > ::FillPointers(GeneralTree < Object >* tree)
{
tree -> PreorderTraversal(AddPointer, this );
}
template < typename Object >
GeneralIterator < Object >* GetElementsIterator(GeneralTree < Object >* tree)
{
return new ElementsIterator < Object > (tree);
}
template < typename Object >
GeneralIterator < Object >* GeneralTree < Object > ::ElementsIterator()
{
return GetElementsIterator < Object > ( this );
}
template < typename Object >
class NodesIterator : public GeneralIterator < TreeNode < Object > >
{
public :
NodesIterator(GeneralTree < Object >* tree)
{
_current = - 1 ;
_count = tree -> Size();
_elements = new TreeNode < Object >* [_count];
this -> FillPointers(tree);
_current = - 1 ;
}
~ NodesIterator()
{
delete _elements;
}
TreeNode < Object >* Next()
{
++ _current;
if (_current < _count)
return _elements[_current];
else
return NULL;
}
void Reset()
{
_current = - 1 ;
}
private :
TreeNode < Object >** _elements;
int _current;
int _count;
void FillPointers(GeneralTree < Object >* tree);
// friend functions
template < typename T >
friend bool AddNodePointer(TreeNode < T >* v, void * param);
};
template < typename T >
bool AddNodePointer(TreeNode < T >* v, void * param)
{
NodesIterator < T >* itr = (NodesIterator < T >* )param;
++ (itr -> _current);
(itr -> _elements)[itr -> _current] = v;
return false ;
}
template < typename Object >
void NodesIterator < Object > ::FillPointers(GeneralTree < Object >* tree)
{
tree -> PreorderTraversal(AddNodePointer, this );
}
template < typename Object >
GeneralIterator < TreeNode < Object > >* GetNodesIterator(GeneralTree < Object >* tree)
{
return new NodesIterator < Object > (tree);
}
template < typename Object >
GeneralIterator < TreeNode < Object > >* GeneralTree < Object > ::NodesIterator()
{
return GetNodesIterator < Object > ( this );
}
template < typename Object >
inline bool GeneralTree < Object > ::IsInternal( const TreeNode < Object >* v) const
{
return v -> firstChild != NULL;
}
template < typename Object >
inline bool GeneralTree < Object > ::IsExternal( const TreeNode < Object >* v) const
{
return v -> firstChild == NULL;
}
template < typename Object >
inline bool GeneralTree < Object > ::IsRoot( const TreeNode < Object >* v) const
{
return v -> parent == NULL;
}
template < typename Object >
inline int GeneralTree < Object > ::Size() const
{
return this -> _count;
}
template < typename Object >
void GeneralTree < Object > ::SwapElement(TreeNode < Object >* v, TreeNode < Object >* w)
{
Object tem = v -> element;
v -> element = w -> element;
w -> element = tem;
}
template < typename Object >
void GeneralTree < Object > ::SetElement(TreeNode < Object >* v, const Object & element)
{
v -> element = element;
}
template < typename Object >
TreeNode < Object >* GeneralTree < Object > ::Insert(TreeNode < Object >* parent, const Object & element)
{
// Create the new node
TreeNode < Object >* pNewNode = new TreeNode < Object > ();
pNewNode -> element = element;
pNewNode -> parent = parent;
pNewNode -> firstChild = NULL;
pNewNode -> nextSibling = NULL;
// Insert the new node
if (parent -> firstChild == NULL)
{
parent -> firstChild = pNewNode;
}
else
{
TreeNode < Object >* pChild = parent -> firstChild;
while (pChild -> nextSibling != NULL) pChild = pChild -> nextSibling;
pChild -> nextSibling = pNewNode;
}
// increment the count
++ this -> _count;
return pNewNode;
}
template < typename Object >
TreeNode < Object >* GeneralTree < Object > ::InsertAfter(TreeNode < Object >* previousSibling,
const Object & element)
{
// Create the new node
TreeNode < Object >* pNewNode = new TreeNode < Object > ();
pNewNode -> element = element;
pNewNode -> parent = previousSibling -> parent;
pNewNode -> firstChild = NULL;
// Connect new node with its previous node
pNewNode -> nextSibling = previousSibling -> nextSibling;
previousSibling -> nextSibling = pNewNode;
// Increment the count
++ this -> _count;
return pNewNode;
}
template < typename Object >
bool FreeNode(TreeNode < Object >* v, void * param)
{
int * size = ( int * )param;
-- ( * size);
delete v;
return false ;
}
template < typename Object >
void GeneralTree < Object > ::Remove(TreeNode < Object >* v)
{
if (v -> parent != NULL)
{
// find the previous sibling
TreeNode < Object >* pChild = (v -> parent) -> firstChild;
if (pChild == v)
v -> parent -> firstChild = NULL;
else
{
while (pChild -> nextSibling != v) pChild = pChild -> nextSibling;
// adjust the tree structure
pChild -> nextSibling = v -> nextSibling;
}
// free all the children and itself
}
this -> PostorderTraversal(FreeNode, & ( this -> _count),v);
}
template < typename Object >
void GeneralTree < Object > ::Remove( const Object & element)
{
TreeNode < Object >* pRemovedNode = Find(element);
this -> Remove(pRemovedNode);
}
template < typename Object >
struct TestParam
{
Object * pElement;
TreeNode < Object >* pNode;
};
template < typename Object >
bool TestElement(TreeNode < Object >* v, void * param)
{
// the param is an array,
// in which the first element stores the pointer to the element
// and the second element will store the pointer to the found node
TestParam < Object >* pTestParam = (TestParam < Object >* )param;
Object * pElement = pTestParam -> pElement;
if (v -> element == * pElement)
{
pTestParam -> pNode = v; // set the found node
return true ; // it is done.
}
else
return false ;
}
template < typename Object >
TreeNode < Object >* GeneralTree < Object > ::Find( const Object & element)
{
Object findingElement = element;
TestParam < Object > testParam;
testParam.pElement = & findingElement;
this -> PreorderTraversal(TestElement, & testParam);
return testParam.pNode;
}
template < typename Object >
int GeneralTree < Object > ::GetHeight( const TreeNode < Object >* v) const
{
if ( this -> IsExternal(v))
return 0 ;
else
{
int maxChildHeight = 0 ;
TreeNode < Object > pChild = v -> firstChild;
while (pChild != NULL)
{
int childHeight = this -> GetHeight(pChild);
if (childHeight > maxChildHeight)
maxChildHeight = childHeight;
}
return maxChildHeight + 1 ;
}
}
template < typename Object >
int GeneralTree < Object > ::GetDepth( const TreeNode < Object >* v) const
{
if ( this -> IsRoot(v))
return 0 ;
else
return 1 + this -> GetDepth(v -> parent);
}
template < typename Object >
bool GeneralTree < Object > ::PreorderTraversal(Action action,
void * param, TreeNode < Object >* pNode)
{
if (pNode == NULL) pNode = this -> _root;
// visit the node
bool isDone = action(pNode, param);
if (isDone == false )
{
// traverse the children
TreeNode < Object >* pChild = pNode -> firstChild;
while (pChild != NULL)
{
bool isDone = this -> PreorderTraversal(action,
param, pChild);
if (isDone)
break ;
else
pChild = pChild -> nextSibling;
}
}
return isDone;
}
template < typename Object >
bool GeneralTree < Object > ::PostorderTraversal(Action action,
void * param, TreeNode < Object >* pNode)
{
if (pNode == NULL) pNode = this -> _root;
// traverse the children
TreeNode < Object >* pChild = pNode -> firstChild;
while (pChild != NULL)
{
bool isChildDone = this -> PostorderTraversal(action, param, pChild);
if (isChildDone)
return true ;
else
pChild = pChild -> nextSibling;
}
// visit the element
return action(pNode, param);
}
#endif
测试代码:
代码
#include
<
iostream
>
#include < string >
#include " GeneralTree.h "
using namespace std;
bool display(TreeNode < string >* v, void * param)
{
GeneralTree < string >* tree = (GeneralTree < string >* )param;
int depth = tree -> GetDepth(v);
string prefix = "" ;
for ( int i = 0 ; i < depth; i ++ ) prefix += " ---- " ;
cout << prefix << v -> element << endl;
return false ;
}
bool addPrefix(TreeNode < string >* v, void * param)
{
string * pStr = ( string * )param;
v -> element = * pStr + v -> element;
return false ;
}
int main()
{
// construct the tree
GeneralTree < string > tree( " Paper " );
TreeNode < string >* insertedNode = tree.Insert(tree.GetRoot(), " Title " );
insertedNode = tree.InsertAfter(insertedNode, " Abstract " );
insertedNode = tree.InsertAfter(insertedNode, " $1 " );
TreeNode < string >* insertedChild = tree.Insert(insertedNode, " $1.1 " );
insertedChild = tree.InsertAfter(insertedChild, " $1.2 " );
insertedNode = tree.InsertAfter(insertedNode, " $2 " );
insertedChild = tree.Insert(insertedNode, " $2.1 " );
insertedChild = tree.InsertAfter(insertedChild, " $2.2 " );
insertedChild = tree.InsertAfter(insertedChild, " $2.3 " );
insertedNode = tree.InsertAfter(insertedNode, " $3 " );
insertedChild = tree.Insert(insertedNode, " $3.1 " );
insertedChild = tree.InsertAfter(insertedChild, " $3.2 " );
insertedNode = tree.InsertAfter(insertedNode, " References " );
// display the tree
cout << " Preorder traversal: " << endl;
tree.PreorderTraversal(display, & tree);
cout << " Postorder traversal: " << endl;
tree.PostorderTraversal(display, & tree);
// edit the element
TreeNode < string >* pFoundNode = tree.Find( " $3 " );
tree.SetElement(pFoundNode, " $3 cource " );
tree.SwapElement(tree.Find( " $3.1 " ),tree.Find( " $3.2 " ));
tree.Remove( " $1 " );
cout << " after altering the elements " << endl;
tree.PreorderTraversal(display, & tree);
// test the node
cout << " check if internal: " << (tree.IsInternal(pFoundNode) ? " true " : " false " ) << endl;
cout << " check if external: " << (tree.IsExternal(pFoundNode) ? " true " : " false " ) << endl;
cout << " check if root: " << (tree.IsRoot(pFoundNode) ? " true " : " false " ) << endl;
cout << " size: " << tree.Size() << endl;
// Iterator
cout << " Traverse elements: " << endl;
GeneralIterator < string >* itr = tree.ElementsIterator();
string * pStr;
while ((pStr = itr -> Next()) != NULL) cout << * pStr << endl;
delete itr;
cout << " Traverse nodes: " << endl;
GeneralIterator < TreeNode < string > >* nodesItr = tree.NodesIterator();
TreeNode < string >* pNode;
while ((pNode = nodesItr -> Next()) != NULL)
cout << " Node: " << string ( 4 * tree.GetDepth(pNode), ' - ' ) << pNode -> element << endl;
return 0 ;
}
#include < string >
#include " GeneralTree.h "
using namespace std;
bool display(TreeNode < string >* v, void * param)
{
GeneralTree < string >* tree = (GeneralTree < string >* )param;
int depth = tree -> GetDepth(v);
string prefix = "" ;
for ( int i = 0 ; i < depth; i ++ ) prefix += " ---- " ;
cout << prefix << v -> element << endl;
return false ;
}
bool addPrefix(TreeNode < string >* v, void * param)
{
string * pStr = ( string * )param;
v -> element = * pStr + v -> element;
return false ;
}
int main()
{
// construct the tree
GeneralTree < string > tree( " Paper " );
TreeNode < string >* insertedNode = tree.Insert(tree.GetRoot(), " Title " );
insertedNode = tree.InsertAfter(insertedNode, " Abstract " );
insertedNode = tree.InsertAfter(insertedNode, " $1 " );
TreeNode < string >* insertedChild = tree.Insert(insertedNode, " $1.1 " );
insertedChild = tree.InsertAfter(insertedChild, " $1.2 " );
insertedNode = tree.InsertAfter(insertedNode, " $2 " );
insertedChild = tree.Insert(insertedNode, " $2.1 " );
insertedChild = tree.InsertAfter(insertedChild, " $2.2 " );
insertedChild = tree.InsertAfter(insertedChild, " $2.3 " );
insertedNode = tree.InsertAfter(insertedNode, " $3 " );
insertedChild = tree.Insert(insertedNode, " $3.1 " );
insertedChild = tree.InsertAfter(insertedChild, " $3.2 " );
insertedNode = tree.InsertAfter(insertedNode, " References " );
// display the tree
cout << " Preorder traversal: " << endl;
tree.PreorderTraversal(display, & tree);
cout << " Postorder traversal: " << endl;
tree.PostorderTraversal(display, & tree);
// edit the element
TreeNode < string >* pFoundNode = tree.Find( " $3 " );
tree.SetElement(pFoundNode, " $3 cource " );
tree.SwapElement(tree.Find( " $3.1 " ),tree.Find( " $3.2 " ));
tree.Remove( " $1 " );
cout << " after altering the elements " << endl;
tree.PreorderTraversal(display, & tree);
// test the node
cout << " check if internal: " << (tree.IsInternal(pFoundNode) ? " true " : " false " ) << endl;
cout << " check if external: " << (tree.IsExternal(pFoundNode) ? " true " : " false " ) << endl;
cout << " check if root: " << (tree.IsRoot(pFoundNode) ? " true " : " false " ) << endl;
cout << " size: " << tree.Size() << endl;
// Iterator
cout << " Traverse elements: " << endl;
GeneralIterator < string >* itr = tree.ElementsIterator();
string * pStr;
while ((pStr = itr -> Next()) != NULL) cout << * pStr << endl;
delete itr;
cout << " Traverse nodes: " << endl;
GeneralIterator < TreeNode < string > >* nodesItr = tree.NodesIterator();
TreeNode < string >* pNode;
while ((pNode = nodesItr -> Next()) != NULL)
cout << " Node: " << string ( 4 * tree.GetDepth(pNode), ' - ' ) << pNode -> element << endl;
return 0 ;
}