//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TPGeGList.h // = Version : ver2.0 // = Author : xlc // = CreateDate : 2002-09-09 // = Description: 类的声明 // = Maintainers: cpp中176行的temp变量没有声明,如何编译? // //-----------------------------------------------------------------------------+ #ifndef _TPGEGLIST_H_ #define _TPGEGLIST_H_ //递归链或图链,方便链动态组建和链高级操作 //每个链结点都代表和管理由本结点和后续链组成的链。 template class TPGeGList { public: //构造 TPGeGList(); //析构,有后续子环路时不能调用下列函数!!! virtual ~TPGeGList(); virtual void DCNNext(); virtual void CNNext(TPGeGList* pList); //数据 const T& GetData()const; const T& GetData(long i)const; T& Data(); T& Data(long i); //释放所有后续结点,本结点成为终止结点 void ReleaseAll(); //链接 void SetNext(TPGeGList* pList); //插入合并 void InsertNext(TPGeGList* pList); //摘取长度为num的后续子链,,num must be >0 and valid!!! TPGeGList* FetchNext(long num = 1); //删除长度为num的后续子链 void DelNext(long num = 1); //遍历,有后续子环路时不能调用下列函数!! long Length()const; TPGeGList* Next()const; TPGeGList* GetAt(long i)const; TPGeGList* GetTail()const; bool IsClosed()const; //返回新链首,如果本结点非链首,将在本结点处形成分叉!如果是环路将保持环路 TPGeGList* Reverse(); const TPGeGList* Find(T&t)const; protected: T data; TPGeGList *next; }; template TPGeGList::TPGeGList() : next(NULL) { } template TPGeGList::~TPGeGList() { //析构时需保证前链接已经断开!! ReleaseAll(); } template const T& TPGeGList::GetData() const { return data; } template T& TPGeGList::Data() { return data; } template const T& TPGeGList::GetData(long i) const { return GetAt(i)->GetData(); } template T& TPGeGList::Data(long i) { return GetAt(i)->Data(); } template void TPGeGList::SetNext(TPGeGList*pList) { next = pList; } template void TPGeGList::CNNext(TPGeGList*pList) { next = pList; } template void TPGeGList::DCNNext() { next = NULL; } template void TPGeGList::DelNext(long num/* = 1*/) { delete FetchNext(num); } template TPGeGList* TPGeGList::Next() const { return next; } template bool TPGeGList::IsClosed() const { return GetTail()->Next() == this; } template const TPGeGList* TPGeGList::Find(T&t) const { if (data == t) { return this; } for (const TPGeGList* p = Next();p != NULL && p != this;p = p->Next()) { if (p->GetData() == t) { return p; } } return NULL; } template TPGeGList* TPGeGList::Reverse() { TPGeGList *pPre = this,*pCur = Next(); while(pCur != NULL && pCur != this) { TPGeGList* temp = pCur->Next(); pCur->SetNext(pPre); pPre = pCur; pCur = temp; } if (pCur == NULL) { SetNext(NULL); return pPre; } else { SetNext(pPre); return this; } } template long TPGeGList::Length() const { long count = 1; for (TPGeGList*pCur = Next();pCur != NULL && pCur != this;pCur = pCur->Next()) { count++; } return count; } template TPGeGList* TPGeGList::GetAt(long i) const { const TPGeGList*pCur = this; for (long j = 0;jNext()); return (TPGeGList*)pCur; } template TPGeGList* TPGeGList::GetTail() const { const TPGeGList*pCur; for (pCur = this;pCur->Next() != this && pCur->Next() != NULL;pCur = pCur->Next()); return (TPGeGList*)pCur; } template void TPGeGList::InsertNext(TPGeGList*pList) { TPGeGList*pOldNext = Next(); CNNext(pList); if (pOldNext != NULL) { pList->GetTail()->CNNext(pOldNext); } } template TPGeGList* TPGeGList::FetchNext(long num) { TPGeGList*pOldNext = Next(); TPGeGList*pLast = GetAt(num); TPGeGList*pTemp = pLast->Next(); if (pTemp != NULL) { pLast->DCNNext(); CNNext(pTemp); } return pOldNext; } template void TPGeGList::ReleaseAll() { for (TPGeGList *pCur = Next();pCur != NULL && pCur != this;) { TPGeGList*temp = pCur->Next(); pCur->SetNext(NULL); delete pCur; pCur = temp; } SetNext(NULL); } #endif