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