//-----------------------------------------------------------------------------+ // 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 TBinTree { public: //contruct/distruct TBinTree(TBinTree*pParentTree = NULL); TBinTree(const TBinTree&bTree); TBinTree& operator=(const TBinTree&bTree); void SetLeftChild(TBinTree*pTree); void SetRightChild(TBinTree*pTree); TBinTree* FetchLeft(); TBinTree* FetchRight(); void ReleaseLeft(); void ReleaseRight(); void Clear(); virtual ~TBinTree(); //direct access T& NodeData(); TBinTree* &LeftChild(); TBinTree* &RightChild(); TBinTree* &Parent(); TBinTree* GetRoot() const; //const access const T& GetNodeData() const; const TBinTree* GetRightChild() const; const TBinTree* GetLeftChild() const; const TBinTree* 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) const; bool operator!=(const TBinTree& t) const; bool operator >(const TBinTree& t) const; bool operator <(const TBinTree& t) const; //other void SwapChild(); long Find(const T&t,TTable* >&trees) const; void GetPath(TTable&path) const;//0为左,1为右 long GetLeafNum() const; void GetLeafNodes(TTable*>&nodes) const; protected: T data; TBinTree *left,*right,*pParent; }; template TBinTree::TBinTree(TBinTree*pParentTree) : left(NULL),right(NULL),pParent(pParentTree) { } template TBinTree::TBinTree(const TBinTree&bTree) : left(NULL),right(NULL),pParent(NULL) { *this = bTree; } template void TBinTree::ReleaseLeft() { if (left != NULL) { delete left; } left = NULL; } template void TBinTree::ReleaseRight() { if(right != NULL) { delete right; } right = NULL; } template void TBinTree::Clear() { ReleaseLeft(); ReleaseRight(); } template TBinTree::~TBinTree() { Clear(); } template T& TBinTree::NodeData() { return data; } template TBinTree* & TBinTree::LeftChild() { return left; } template TBinTree* & TBinTree::RightChild() { return right; } template TBinTree* & TBinTree::Parent() { return pParent; } template const T& TBinTree::GetNodeData() const { return data; } template const TBinTree* TBinTree::GetRightChild() const { return right; } template const TBinTree* TBinTree::GetLeftChild() const { return left; } template const TBinTree* TBinTree::GetParent() const { return pParent; } //attribute template bool TBinTree::IsLeftEmpty() const { return left == NULL; } template bool TBinTree::IsRightEmpty() const { return right == NULL; } template bool TBinTree::IsRoot() const { return pParent == NULL; } template bool TBinTree::IsChild() const { return pParent != NULL; } template bool TBinTree::IsLeaf() const { return !IsParent(); } template bool TBinTree::IsParent() const { return !IsLeftEmpty() || !IsRightEmpty(); } template bool TBinTree::IsRightChild() const { return IsChild() ? pParent->GetRightChild() == this:false; } template bool TBinTree::IsLeftChild() const { return IsChild() ? pParent->GetLeftChild() == this:false; } template bool TBinTree::operator != (const TBinTree& t) const { return !(*this == t); } template bool TBinTree::operator > (const TBinTree& t) const { return data > t.GetNodeData(); } template bool TBinTree::operator < (const TBinTree& t) const { return data < t.GetNodeData(); } //other template void TBinTree::SwapChild() { Exchange(right,left); } template TBinTree* TBinTree::GetRoot() const { TBinTree* pTree = (TBinTree*)this; while(pTree->IsChild()) { pTree = (TBinTree*)(pTree->GetParent()); } return pTree; } template void TBinTree::SetLeftChild(TBinTree*pTree) { if(pTree == left) { return; } if(pTree != NULL) { pTree->Parent() = this; } ReleaseLeft(); left = pTree; } template void TBinTree::SetRightChild(TBinTree*pTree) {//双向 if(pTree == right) { return; } ReleaseRight(); right = pTree; if(pTree != NULL) { pTree->Parent() = this; } } template TBinTree* TBinTree::FetchLeft() { TBinTree*p = left; left = NULL; if(p != NULL) { p->Parent() = NULL; } return p; } template TBinTree* TBinTree::FetchRight() { TBinTree*p = right; right = NULL; if(p != NULL) { p->Parent() = NULL; } return p; } template long TBinTree::GetLeafNum() const { if(IsLeaf()) { return 1; } long res = 0; if(!IsLeftEmpty()) { res += GetLeftChild()->GetLeafNum(); } if(!IsRightEmpty()) { res += GetRightChild()->GetLeafNum(); } return res; } template void TBinTree::GetLeafNodes(TTable*>&nodes) const { if(IsLeaf()) { this->nodeList.AddTail(this); } else { if(!IsLeftEmpty()) { GetLeftChild()->GetLeafNodes(nodes); } if(!IsRightEmpty()) { GetRightChild()->GetLeafNodes(nodes); } } } template void TBinTree::GetPath(TTable&path) const { if(IsLeftChild()) { GetParent()->GetPath(path); path.AddTail(0); } else if(IsRightChild()) { GetParent()->GetPath(path); path.AddTail(1); } } template long TBinTree::Find(const T&t,TTable* >&trees) const { if(data == t) { trees.AddTail(this); } if(!IsLeftEmpty()) { left->Find(t,trees); } if(!IsRightEmpty()) { right->Find(t,trees); } return trees.GetLength(); } template TBinTree& TBinTree::operator=(const TBinTree&t) { data = t.GetNodeData(); if(!t.IsLeftEmpty()) { SetLeftChild(new TBinTree(*t.GetLeftChild())); } if(!t.IsRightEmpty()) { SetRightChild(new TBinTree(*t.GetRightChild())); } return *this; } template bool TBinTree::operator==(const TBinTree&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