422 lines
7.0 KiB
C++
422 lines
7.0 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TBinTree.h
|
|
// = Version : ver2.0
|
|
// = Author : xlc
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: 类的声明
|
|
// = Maintainers: nodeList没有定义,所以我认为该类没有用
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#ifndef _TBINTREE_H_
|
|
#define _TBINTREE_H_
|
|
|
|
#ifndef _TTABLE_H_
|
|
#include "TTable.h"
|
|
#endif
|
|
|
|
//二叉树
|
|
template<class T> class TBinTree
|
|
{
|
|
public:
|
|
//contruct/distruct
|
|
TBinTree(TBinTree<T>*pParentTree = NULL);
|
|
TBinTree(const TBinTree<T>&bTree);
|
|
TBinTree<T>& operator=(const TBinTree<T>&bTree);
|
|
void SetLeftChild(TBinTree<T>*pTree);
|
|
void SetRightChild(TBinTree<T>*pTree);
|
|
TBinTree<T>* FetchLeft();
|
|
TBinTree<T>* FetchRight();
|
|
void ReleaseLeft();
|
|
void ReleaseRight();
|
|
void Clear();
|
|
virtual ~TBinTree();
|
|
|
|
//direct access
|
|
T& NodeData();
|
|
TBinTree<T>* &LeftChild();
|
|
TBinTree<T>* &RightChild();
|
|
TBinTree<T>* &Parent();
|
|
TBinTree<T>* GetRoot() const;
|
|
|
|
//const access
|
|
const T& GetNodeData() const;
|
|
const TBinTree<T>* GetRightChild() const;
|
|
const TBinTree<T>* GetLeftChild() const;
|
|
const TBinTree<T>* GetParent() const;
|
|
|
|
//attribute
|
|
bool IsLeftEmpty() const;
|
|
bool IsRightEmpty() const;
|
|
bool IsRoot() const;
|
|
bool IsChild() const;
|
|
bool IsLeaf() const;
|
|
bool IsParent() const;
|
|
bool IsRightChild() const;
|
|
bool IsLeftChild() const;
|
|
|
|
bool operator==(const TBinTree<T>& t) const;
|
|
bool operator!=(const TBinTree<T>& t) const;
|
|
bool operator >(const TBinTree<T>& t) const;
|
|
bool operator <(const TBinTree<T>& t) const;
|
|
|
|
//other
|
|
void SwapChild();
|
|
long Find(const T&t,TTable<TBinTree<T>* >&trees) const;
|
|
void GetPath(TTable<short>&path) const;//0为左,1为右
|
|
long GetLeafNum() const;
|
|
void GetLeafNodes(TTable<TBinTree<T>*>&nodes) const;
|
|
|
|
protected:
|
|
T data;
|
|
TBinTree<T> *left,*right,*pParent;
|
|
};
|
|
|
|
|
|
template<class T>
|
|
TBinTree<T>::TBinTree(TBinTree<T>*pParentTree)
|
|
: left(NULL),right(NULL),pParent(pParentTree)
|
|
{
|
|
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>::TBinTree(const TBinTree<T>&bTree)
|
|
: left(NULL),right(NULL),pParent(NULL)
|
|
{
|
|
*this = bTree;
|
|
}
|
|
|
|
template<class T>
|
|
void TBinTree<T>::ReleaseLeft()
|
|
{
|
|
if (left != NULL)
|
|
{
|
|
delete left;
|
|
}
|
|
left = NULL;
|
|
}
|
|
|
|
template<class T>
|
|
void TBinTree<T>::ReleaseRight()
|
|
{
|
|
if(right != NULL)
|
|
{
|
|
delete right;
|
|
}
|
|
right = NULL;
|
|
}
|
|
|
|
template<class T>
|
|
void TBinTree<T>::Clear()
|
|
{
|
|
ReleaseLeft();
|
|
ReleaseRight();
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>::~TBinTree()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
template<class T>
|
|
T& TBinTree<T>::NodeData()
|
|
{
|
|
return data;
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>* & TBinTree<T>::LeftChild()
|
|
{
|
|
return left;
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>* & TBinTree<T>::RightChild()
|
|
{
|
|
return right;
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>* & TBinTree<T>::Parent()
|
|
{
|
|
return pParent;
|
|
}
|
|
|
|
template<class T>
|
|
const T& TBinTree<T>::GetNodeData() const
|
|
{
|
|
return data;
|
|
}
|
|
|
|
template<class T>
|
|
const TBinTree<T>* TBinTree<T>::GetRightChild() const
|
|
{
|
|
return right;
|
|
}
|
|
|
|
template<class T>
|
|
const TBinTree<T>* TBinTree<T>::GetLeftChild() const
|
|
{
|
|
return left;
|
|
}
|
|
|
|
template<class T>
|
|
const TBinTree<T>* TBinTree<T>::GetParent() const
|
|
{
|
|
return pParent;
|
|
}
|
|
|
|
//attribute
|
|
template<class T>
|
|
bool TBinTree<T>::IsLeftEmpty() const
|
|
{
|
|
return left == NULL;
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::IsRightEmpty() const
|
|
{
|
|
return right == NULL;
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::IsRoot() const
|
|
{
|
|
return pParent == NULL;
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::IsChild() const
|
|
{
|
|
return pParent != NULL;
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::IsLeaf() const
|
|
{
|
|
return !IsParent();
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::IsParent() const
|
|
{
|
|
return !IsLeftEmpty() || !IsRightEmpty();
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::IsRightChild() const
|
|
{
|
|
return IsChild() ? pParent->GetRightChild() == this:false;
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::IsLeftChild() const
|
|
{
|
|
return IsChild() ? pParent->GetLeftChild() == this:false;
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::operator != (const TBinTree<T>& t) const
|
|
{
|
|
return !(*this == t);
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::operator > (const TBinTree<T>& t) const
|
|
{
|
|
return data > t.GetNodeData();
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::operator < (const TBinTree<T>& t) const
|
|
{
|
|
return data < t.GetNodeData();
|
|
}
|
|
|
|
//other
|
|
template<class T>
|
|
void TBinTree<T>::SwapChild()
|
|
{
|
|
Exchange(right,left);
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>* TBinTree<T>::GetRoot() const
|
|
{
|
|
TBinTree<T>* pTree = (TBinTree<T>*)this;
|
|
while(pTree->IsChild())
|
|
{
|
|
pTree = (TBinTree<T>*)(pTree->GetParent());
|
|
}
|
|
return pTree;
|
|
}
|
|
|
|
template<class T>
|
|
void TBinTree<T>::SetLeftChild(TBinTree<T>*pTree)
|
|
{
|
|
if(pTree == left)
|
|
{
|
|
return;
|
|
}
|
|
if(pTree != NULL)
|
|
{
|
|
pTree->Parent() = this;
|
|
}
|
|
ReleaseLeft();
|
|
left = pTree;
|
|
}
|
|
|
|
template<class T>
|
|
void TBinTree<T>::SetRightChild(TBinTree<T>*pTree)
|
|
{//双向
|
|
if(pTree == right)
|
|
{
|
|
return;
|
|
}
|
|
ReleaseRight();
|
|
right = pTree;
|
|
if(pTree != NULL)
|
|
{
|
|
pTree->Parent() = this;
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>* TBinTree<T>::FetchLeft()
|
|
{
|
|
TBinTree<T>*p = left;
|
|
left = NULL;
|
|
if(p != NULL)
|
|
{
|
|
p->Parent() = NULL;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>* TBinTree<T>::FetchRight()
|
|
{
|
|
TBinTree<T>*p = right;
|
|
right = NULL;
|
|
if(p != NULL)
|
|
{
|
|
p->Parent() = NULL;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
template<class T>
|
|
long TBinTree<T>::GetLeafNum() const
|
|
{
|
|
if(IsLeaf())
|
|
{
|
|
return 1;
|
|
}
|
|
long res = 0;
|
|
|
|
if(!IsLeftEmpty())
|
|
{
|
|
res += GetLeftChild()->GetLeafNum();
|
|
}
|
|
if(!IsRightEmpty())
|
|
{
|
|
res += GetRightChild()->GetLeafNum();
|
|
}
|
|
return res;
|
|
}
|
|
|
|
template<class T>
|
|
void TBinTree<T>::GetLeafNodes(TTable<TBinTree<T>*>&nodes) const
|
|
{
|
|
if(IsLeaf())
|
|
{
|
|
this->nodeList.AddTail(this);
|
|
}
|
|
else
|
|
{
|
|
if(!IsLeftEmpty())
|
|
{
|
|
GetLeftChild()->GetLeafNodes(nodes);
|
|
}
|
|
if(!IsRightEmpty())
|
|
{
|
|
GetRightChild()->GetLeafNodes(nodes);
|
|
}
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
void TBinTree<T>::GetPath(TTable<short>&path) const
|
|
{
|
|
if(IsLeftChild())
|
|
{
|
|
GetParent()->GetPath(path);
|
|
path.AddTail(0);
|
|
}
|
|
else if(IsRightChild())
|
|
{
|
|
GetParent()->GetPath(path);
|
|
path.AddTail(1);
|
|
}
|
|
}
|
|
|
|
template<class T>
|
|
long TBinTree<T>::Find(const T&t,TTable<TBinTree<T>* >&trees) const
|
|
{
|
|
if(data == t)
|
|
{
|
|
trees.AddTail(this);
|
|
}
|
|
if(!IsLeftEmpty())
|
|
{
|
|
left->Find(t,trees);
|
|
}
|
|
if(!IsRightEmpty())
|
|
{
|
|
right->Find(t,trees);
|
|
}
|
|
return trees.GetLength();
|
|
}
|
|
|
|
template<class T>
|
|
TBinTree<T>& TBinTree<T>::operator=(const TBinTree<T>&t)
|
|
{
|
|
data = t.GetNodeData();
|
|
if(!t.IsLeftEmpty())
|
|
{
|
|
SetLeftChild(new TBinTree<T>(*t.GetLeftChild()));
|
|
}
|
|
if(!t.IsRightEmpty())
|
|
{
|
|
SetRightChild(new TBinTree<T>(*t.GetRightChild()));
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
template<class T>
|
|
bool TBinTree<T>::operator==(const TBinTree<T>&t) const
|
|
{
|
|
if(data != t.GetNodeData())
|
|
{
|
|
return false;
|
|
}
|
|
if((!IsLeftEmpty() && t.IsLeftEmpty()) || (IsLeftEmpty() && !t.IsLeftEmpty())
|
|
(!IsRightEmpty() && t.IsRightEmpty()) || (IsRightEmpty() && !t.IsRightEmpty()))
|
|
{
|
|
return false;
|
|
}
|
|
if((!IsLeftEmpty() && !t.IsLeftEmpty()) && *left != *(t.GetLeftChild()))
|
|
{
|
|
return false;
|
|
}
|
|
if((!IsRightEmpty() && !t.IsRightEmpty()) && *right != *(t.GetRightChild()))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
#endif |