树是一种非线性的数据结构,最常用到的是树和二叉树,其中又以二叉树更为实用。
下面是二叉树的一个C++实现:
/*btree.h*/
#ifndef __BINARY_TREE_H__
#define __BINARY_TREE_H__
#include <assert.h>
#include <crtdbg.h>
template<typename T>
class BTNode
{
public:
T data;
BTNode<T> *parent;
BTNode<T> *left;
BTNode<T> *right;
BTNode(
T data = T(),
BTNode<T> *parent = NULL,
BTNode<T> *left = NULL,
BTNode<T> *right = NULL
) : data(data), parent(parent), left(left), right(right) {}
};
template<typename T>
class BTree
{
public://constructors and copying controling functions
BTree(BTNode<T> *initroot = NULL);
BTree(const BTree<T>& other);
virtual ~BTree();
BTree<T>& operator=(const BTree<T>& other);
void Clone(const BTree<T>& other);
void Attach(BTNode<T> *p);//node cannot be any node in this tree.
void Destroy();// make empty
public://utilizations
T& GetNodeData(BTNode<T> *p);
T GetNodeData(const BTNode<T> *p) const;
void SetNodeData(BTNode<T> *p, const T &data);
BTNode<T>*& GetRoot();
BTNode<T>* GetRoot() const;
BTNode<T>*& GetParent(BTNode<T> *p);
BTNode<T>* GetParent(const BTNode<T> *p) const;
BTNode<T>*& GetLeftChild(BTNode<T> *p);
BTNode<T>* GetLeftChild(const BTNode<T> *p) const;
BTNode<T>*& GetRightChild(BTNode<T> *p);
BTNode<T>* GetRightChild(const BTNode<T> *p) const;
BTNode<T>*& GetLeftSibling(BTNode<T> *p);
BTNode<T>* GetLeftSiblig(const BTNode<T> *p) const;
BTNode<T>*& GetRightSibling(BTNode<T> *p);
BTNode<T>* GetRightSibling(const BTNode<T> *p) const;
int IsEmpty() const;
public://public interfaces for core operation
typedef void(* funtype)(const T&);
void PreOrderTraverse(funtype Visit) const;
void InOrderTraverse(funtype Visit) const;
void PostOrderTraverse(funtype Visit) const;
unsigned int GetNodesCount() const; // Get how many nodes
unsigned int GetLeafCount() const;
unsigned int GetDepth() const;
private://private function implementing real core operations, like tranversion and recursion operations
BTNode<T>* CloneSubTree(BTNode<T> *p);//clone(deeply copy) the subtree from the node pointet by p.
void DestroySubTree(BTNode<T> *p);
void PreOrderTraverse(const BTNode<T> *p,funtype Visit) const;
void InOrderTraverse(const BTNode<T> *p,funtype Visit) const;
void PostOrderTraverse(const BTNode<T> *p,funtype Visit) const;
void GetNodesCount(const BTNode<T> *p, unsigned int *unCount) const;
void GetLeafCount(const BTNode<T> *p, unsigned int *unCount) const;
unsigned int GetDepth(const BTNode<T> *p) const;
protected:
BTNode<T> *m_pNodeRoot;
};
/*------------------------------------------------------------------------
*constructor and copying controling functions
---------------------------------------------------------------------------*/
template<typename T>
inline BTree<T>::BTree(BTNode<T> *initroot) : m_pNodeRoot(initroot)
{
}
template<typename T>
inline BTree<T>::BTree(const BTree<T>& other) : m_pNodeRoot(NULL)
{
if (NULL != other.m_pNodeRoot)
m_pNodeRoot = CloneSubTree(other.m_pNodeRoot);
}
template<typename T>
inline BTree<T>::~BTree()
{
Destroy();
}
template<typename T>
inline void BTree<T>::Attach(BTNode<T> *p)
{
ASSERT(p);
if(m_pNodeRoot!=NULL)
{
Destroy();
}
m_pNodeRoot = p;
}
template<typename T>
inline BTree<T>& BTree<T>::operator=(const BTree<T> &p)
{
if(this==&p)
{
return *this;
}
if(m_pNodeRoot!=NULL)
{
Destroy();
}
if (NULL != p.m_pNodeRoot)
m_pNodeRoot = CloneSubTree(p.m_pNodeRoot);
else
m_pNodeRoot = NULL;
return *this;
}
template<typename T>
inline void BTree<T>::Clone(const BTree<T> &p)
{
/*if(this==&p)
{
return;
}
if(m_pNodeRoot!=NULL)
{
Destroy();
}
if (NULL != p.m_pNodeRoot)
m_pNodeRoot = CloneSubTree(p.m_pNodeRoot);
else
m_pNodeRoot = NULL;*/
operator=(p);
}
template<typename T>
inline void BTree<T>::Destroy()
{
DestroySubTree(m_pNodeRoot);
m_pNodeRoot = NULL;
}
/*------------------------------------------------------------------
*utilizations,e.g, gets and sets
---------------------------------------------------------------------*/
template<typename T>
inline BTNode<T>*& BTree<T>::GetLeftChild(BTNode<T> *p)
{
ASSERT(p);
return *(&(p->left));
}
template<typename T>
inline BTNode<T>* BTree<T>::GetLeftChild(const BTNode<T> *p) const
{
ASSERT(p);
return p->left;
}
template<typename T>
inline BTNode<T>*& BTree<T>::GetRightChild(BTNode<T> *p)
{
ASSERT(p);
return *(&(p->right));
}
template<typename T>
inline BTNode<T>* BTree<T>::GetRightChild(const BTNode<T> *p) const
{
ASSERT(p);
return p->right;
}
template<typename T>
inline BTNode<T>*& BTree<T>::GetLeftSibling(BTNode<T> *p)
{
ASSERT(p);
if (p->parent)
return *(&(p->parent->left));
else
return *(&(p->parent)); // return NULL;
}
template<typename T>
inline BTNode<T>* BTree<T>::GetLeftSiblig(const BTNode<T> *p) const
{
ASSERT(p);
if (p->parent)
return p->parent->left;
else
return p->parent; // return NULL;
}
template<typename T>
inline BTNode<T>*& BTree<T>::GetRightSibling(BTNode<T> *p)
{
ASSERT(p);
if (p->parent)
return *(&(p->parent->right));
else
return *(&(p->parent)); // return NULL;
}
template<typename T>
inline BTNode<T>* BTree<T>::GetRightSibling(const BTNode<T> *p) const
{
ASSERT(p);
if (p->parent)
return p->parent->right;
else
return p->parent; // return NULL;
}
template<typename T>
inline BTNode<T>*& BTree<T>::GetParent(BTNode<T> *p)
{
ASSERT(p);
return *(&(p->parent));
}
template<typename T>
inline BTNode<T>* BTree<T>::GetParent(const BTNode<T> *p) const
{
ASSERT(p);
return p->parent;
}
template<typename T>
inline T& BTree<T>::GetNodeData(BTNode<T> *p)
{
ASSERT(p);
return p->data;
}
template<typename T>
inline T BTree<T>::GetNodeData(const BTNode<T> *p) const
{
ASSERT(p);
return p->data;
}
template<typename T>
inline void BTree<T>::SetNodeData(BTNode<T> *p, const T &data)
{
ASSERT(p);
p->data = data;
}
template<typename T>
inline int BTree<T>::IsEmpty() const
{
return NULL == m_pNodeRoot;
}
template<typename T>
inline BTNode<T>*& BTree<T>::GetRoot()
{
return *(&(m_pNodeRoot));
}
template<typename T>
inline BTNode<T>* BTree<T>::GetRoot() const
{
return m_pNodeRoot;
}
/*---------------------------------------------------------------------
*public interfaces for core operations
------------------------------------------------------------------------*/
template<typename T>
inline void BTree<T>::PreOrderTraverse(funtype Visit) const
{
PreOrderTraverse(m_pNodeRoot, Visit);
}
template<typename T>
inline void BTree<T>::InOrderTraverse(funtype Visit) const
{
InOrderTraverse(m_pNodeRoot, Visit);
}
template<typename T>
inline void BTree<T>::PostOrderTraverse(funtype Visit) const
{
PostOrderTraverse(m_pNodeRoot, Visit);
}
template<typename T>
inline unsigned int BTree<T>::GetNodesCount() const
{
unsigned int unCount;
GetNodesCount(m_pNodeRoot, &unCount);
return unCount;
}
template<typename T>
inline unsigned int BTree<T>::GetLeafCount() const
{
unsigned int unCount = 0;
GetLeafCount(m_pNodeRoot, &unCount);
return unCount;
}
template<typename T>
inline unsigned int BTree<T>::GetDepth() const
{
// Minus 1 here because I think the root node's depth should be 0.
// So, don't do it if u think the root node's depth should be 1.
return GetDepth(m_pNodeRoot) - 1;
}
/*------------------------------------------------------------------------------
*private functions: implementing recursion operations, tranversion operations and others.
---------------------------------------------------------------------------------*/
template<typename T>
inline BTNode<T>* BTree<T>::CloneSubTree(BTNode<T> *p)
{
if (p)
{
BTNode<T> *pNewNode;
try
{
pNewNode = new BTNode<T>;
}
catch(std::bad_alloc&)
{
return NULL;
}
pNewNode->data = p->data;
pNewNode->parent = p->parent;
pNewNode->left = CloneSubTree(p->left);
pNewNode->right = CloneSubTree(p->right);
return pNewNode;
}
else
return NULL;
}
template<typename T>
inline void BTree<T>::DestroySubTree(BTNode<T> *p)
{
if (p)
{
DestroySubTree(p->left);
DestroySubTree(p->right);
delete p;
}
}
template<typename T>
inline void BTree<T>::PreOrderTraverse(const BTNode<T> *p,funtype Visit) const
{
if (p)
{
Visit(p->data);
PreOrderTraverse(p->left, Visit);
PreOrderTraverse(p->right, Visit);
}
}
template<typename T>
inline void BTree<T>::InOrderTraverse(const BTNode<T> *p,funtype Visit) const
{
if (p)
{
InOrderTraverse(p->left, Visit);
Visit(p->data);
InOrderTraverse(p->right, Visit);
}
}
template<typename T>
inline void BTree<T>::PostOrderTraverse(const BTNode<T> *p,funtype Visit) const
{
if (p)
{
PostOrderTraverse(p->left, Visit);
PostOrderTraverse(p->right, Visit);
Visit(p->data);
}
}
template<typename T>
inline void BTree<T>::GetNodesCount(
const BTNode<T> *p,
unsigned int *unCount
) const
{
ASSERT(unCount);
unsigned int unLeftCount;
unsigned int unRightCount;
if (NULL == p)
*unCount = 0;
else if ((NULL == p->left) && (NULL == p->right))
*unCount = 1;
else
{
GetNodesCount(p->left, &unLeftCount);
GetNodesCount(p->right, &unRightCount);
*unCount = 1 + unLeftCount + unRightCount;
}
}
template<typename T>
inline void BTree<T>::GetLeafCount(
const BTNode<T> *p,
unsigned int *unCount
) const
{
ASSERT(unCount);
if (p)
{
// if the node's left & right children are both NULL, it must be a leaf
if ((NULL == p->left) && (NULL == p->right))
++(*unCount);
GetLeafCount(p->left, unCount);
GetLeafCount(p->right, unCount);
}
}
template<typename T>
inline unsigned int BTree<T>::GetDepth(const BTNode<T> *p) const
{
unsigned int unDepthLeft;
unsigned int unDepthRight;
if (p)
{
unDepthLeft = GetDepth(p->left);
unDepthRight = GetDepth(p->right);
return 1 + // if don't plus 1 here, the tree's depth will be always 0
(unDepthLeft > unDepthRight ? unDepthLeft : unDepthRight);
}
else
return 0;
}
#endif // __BINARY_TREE_H__
8813

被折叠的 条评论
为什么被折叠?



