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