一般树实现

    这里用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

 

 

 

    测试代码:
    

代码
 
   
#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 ;
}

 

转载于:https://www.cnblogs.com/alala666888/archive/2010/12/14/1906045.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值