//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TTree.h // = Version : ver2.0 // = Author : xlc // = CreateDate : 2002-09-09 // = Description: 类的声明 // = Maintainers: // //-----------------------------------------------------------------------------+ #ifndef _TTREE_H_ #define _TTREE_H_ #ifndef _TTABLE_H_ #include "TTable.h" #endif #ifndef _TFOREST_H_ #include "TForest.h" #endif template class TForest; template class TTree { public: TTree(const TTree* tree); TTree(TTree *pParentTree = NULL); virtual ~TTree(); //深拷贝 TTree& operator=(const TTree&tree); //增加子树的四个一般方式,如直接在子森林中增加,则应手动设置子树的pParent. void AppendChild(TTree*pTree = NULL); void AppendForest(TForest&trees); void InsertChild(long i,TTree*pTree = NULL); void InsertFirstChild(TTree*pTree = NULL); //结点数据 T& NodeData(); TTree* &Parent(); TForest& ChildForest(); //直接操作子森林的一般方式 TForest* operator->(); const T& GetNodeData()const; const TTree* GetParent()const; const TForest& GetChildForest()const; long GetChildNum()const; bool IsParent()const; bool IsLeaf()const; bool IsRoot()const; bool IsChild()const; bool IsChildOf(TTree* pTree)const; bool operator==(const TTree&t)const; bool operator!=(const TTree&t)const; bool operator>(const TTree&t)const; bool operator<(const TTree&t)const; //到根结点,如果本身为根则返回this; TTree* GoRoot()const; //到父结点,如无则返回NULL; TTree* GoUp()const; //到当前结点,超出范围则返回NULL TTree* GoDown(); //到第一个子结点,无子结点则返回NULL TTree* GoDownFirst(); //到最后一个子结点,无子结点则返回NULL TTree* GoDownLast(); //到第i个子结点,超出范围则返回NULL TTree* GoDown(long i); //到下一个兄弟结点,最后一个则返回NULL TTree* GoRight(); //到前一个兄弟结点,第一个则返回NULL TTree* GoLeft(); long GetIndexInForest()const; long FindTreeNode(const T&t,TTable* >&trees); void GetPath(TTable&path)const; long GetLeafNum(); void GetLeafNodes(TTable*> &leafs); TTree* GetSameParent(TTree*pTree); protected: T data; //结点数据 TTree* pParent; //父树 TForest forest; //子树森林 }; template TTree::TTree(TTree *pParentTree) : pParent(pParentTree) { } template TTree::TTree(const TTree* tree) : pParent(NULL) { *this = tree; } template TTree::~TTree() { } template void TTree::AppendForest(TForest&trees) { trees.SetParent(this); forest.Conbine(trees); } template T& TTree::NodeData() { return data; } template TTree* & TTree::Parent() { return pParent; } template TForest& TTree::ChildForest() { return forest; } //直接操作子森林的一般方式 template TForest* TTree::operator->() { return &forest; } template const T& TTree::GetNodeData()const { return data; } template const TForest& TTree::GetChildForest()const { return forest; } template const TTree* TTree::GetParent()const { return pParent; } template long TTree::GetChildNum()const { return forest.GetLength(); } template bool TTree::IsParent()const { return !forest.IsEmpty(); } template bool TTree::IsLeaf()const { return !IsParent(); } template bool TTree::IsRoot()const { return GetParent() == NULL; } template bool TTree::IsChild()const { return GetParent() != NULL; } template bool TTree::operator == (const TTree &t)const { return data == t.GetNodeData() && this->GetForest() == t.GetChildForest(); } template bool TTree::operator != (const TTree&t)const { return !(*this == t); } template bool TTree::operator>(const TTree&t)const { return data > t.GetNodeData(); } template bool TTree::operator<(const TTree&t)const { return data < t.GetNodeData(); } template long TTree::GetIndexInForest()const { return IsChild() ? GetParent()->GetChildForest().Find((TTree*)this) : -1; } template void TTree::GetLeafNodes(TTable*>&leafs) { if (IsLeaf()) { leafs.AddTail(this); } else { forest.GetLeafNodes(leafs); } } template long TTree::GetLeafNum() { return IsLeaf() ? 1 : forest.GetLeafNum(); } template void TTree::InsertChild(long i,TTree*pTree) { if (pTree == NULL) { pTree = new TTree; } forest.Insert(i,pTree); pTree->Parent() = this; } template void TTree::InsertFirstChild(TTree*pTree) { if (pTree == NULL) { pTree = new TTree; } forest.InsertHead(pTree); pTree->Parent() = this; } template void TTree::AppendChild(TTree*pTree) { if (pTree == NULL) { pTree = new TTree; } forest.AddTail(pTree); pTree->Parent() = this; } template void TTree::GetPath(TTable&path)const { if (IsChild()) { GetParent()->GetPath(path); path.AddTail(GetIndexInForest()); } } template bool TTree::IsChildOf(TTree*pTree)const { if (!IsChild()) { return false; } if (GetParent() == pTree) { return true; } else { return GetParent()->IsChildOf(pTree); } } template TTree* TTree::GetSameParent(TTree*pTree) { TList* > path1,path2; GetPath(path1); pTree->GetPath(path2); for (path1.MoveToFirst(),path2.MoveToFirst(); !path1.IsOut() && !path2.IsOut() && path1.GetCurData() != path2.GetCurData(); path1.MoveToNext(),path2.MoveToNext()); { path1.MoveToPre(); } return path1.GetCurData(); } template long TTree::FindTreeNode(const T&t,TTable*>&trees) { if (data == t) { trees.AddTail(this); } forest.FindTree(t,trees); return trees.GetLength(); } template TTree* TTree::GoRoot()const { TTree*pTree = (TTree*)this; while (pTree->IsChild()) { pTree = pTree->GoUp(); } return pTree; } template TTree* TTree::GoUp()const { return (TTree*)GetParent(); } template TTree* TTree::GoDown() { return forest.GetCurTree(); } template TTree* TTree::GoDownFirst() { forest.MoveToFirst(); return forest.GetCurTree(); } template TTree* TTree::GoDownLast() { forest.MoveToLast(); return forest.GetCurTree(); } template TTree* TTree::GoDown(long i) { forest.MoveTo(i); return forest.GetCurTree(); } template TTree* TTree::GoLeft() { if (IsRoot()) { return NULL; } TForest &f = Parent()->ChildForest(); if (f.GetCurTree() != this) //所在子树森林的游标未指向本树 { f.MoveTo(GetIndexInForest()); } f.MoveToPre(); return f.GetCurTree(); } template TTree* TTree::GoRight() { if (IsRoot()) { return NULL; } TForest &f = Parent()->ChildForest(); if (f.GetCurTree() != this) //所在子树森林的游标未指向本树 { f.MoveTo(GetIndexInForest()); } f.MoveToNext(); return f.GetCurTree(); } template TTree& TTree::operator=(const TTree&tree) { data = tree.GetNodeData(); forest = tree.GetChildForest(); forest.SetParent(this); return *this; } #endif