//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TPGeGDList.h // = Version : ver2.0 // = Author : xlc // = CreateDate : 2002-09-09 // = Description: 类的声明 双向递归链 // = Maintainers: // //-----------------------------------------------------------------------------+ #ifndef _TPGEGDLIST_H_ #define _TPGEGDLIST_H_ #ifndef _TPGEGLIST_H_ #include "TPGeGList.h" #endif template class TPGeGDList : public TPGeGList { public: TPGeGDList(); //pList!=NULL!!! virtual void CNNext(TPGeGDList*pList); virtual void DCNNext(); //释放所有前面结点,本结点成为起始结点 void ReleaseAllPre(); TPGeGDList*Next() const; TPGeGDList*Pre() const; TPGeGDList* GetTail() const; //如果是环路GetTail与GetHead结果相同 TPGeGDList* GetHead() const; TPGeGDList* GetAt(long i) const; const T& GetData(long i) const; void DCNPre(); void SetPre(TPGeGDList* pList) const; //安全转接,自动断开所有原相关链接,pList!=NULL!!! void CNPre(TPGeGDList*pList); TPGeGDList* FetchNext(long num = 1); //返回新链首,如果本结点非链首,将在本结点处形成分叉!如果是环路将保持环路 TPGeGDList* Reverse(); protected: TPGeGDList* pre; }; template TPGeGDList::TPGeGDList() : pre(NULL) { } template TPGeGDList* TPGeGDList::Next() const { return (TPGeGDList*)this->next; } template TPGeGDList* TPGeGDList::Pre() const { return pre; } template TPGeGDList* TPGeGDList::GetTail() const { return (TPGeGDList*)(TPGeGList::GetTail()); } template const T& TPGeGDList::GetData(long i) const { return GetAt(i)->GetData(); } template void TPGeGDList::SetPre(TPGeGDList* pList) const {//一般不使用! pre = pList; } template void TPGeGDList::DCNNext() { if (this->next != NULL) { this->next->SetPre(NULL); this->next = NULL; } } template void TPGeGDList::DCNPre() { if(pre != NULL) { pre->SetNext(NULL); pre = NULL; } } template TPGeGDList* TPGeGDList::FetchNext(long num/* = 1*/) { return (TPGeGDList*)(TPGeGList::FetchNext(num)); } template void TPGeGDList::CNNext(TPGeGDList*pList) { DCNNext(); pList->DCNPre(); this->SetNext(pList); pList->SetPre(this); } template void TPGeGDList::CNPre(TPGeGDList*pList) { DCNPre(); pList->DCNNext(); SetPre(pList); pList->SetNext(this); } template TPGeGDList* TPGeGDList::GetHead() const { for(const TPGeGDList*pCur = this; pCur->Pre() != NULL && pCur->Pre() != this; pCur = pCur->Pre()); return (TPGeGDList*)this->pCur; } template TPGeGDList* TPGeGDList::GetAt(long i) const { if(i >= 0) { return (TPGeGDList*)(TPGeGList::GetAt(i)); } else { long count = 1; for(TPGeGDList*pCur = Pre(); count< -i && pCur != NULL; count++, pCur = pCur->Pre()); return this->pCur; } } template void TPGeGDList::ReleaseAllPre() { TPGeGDList* pHead = GetHead(); DCNPre(); delete pHead; } template TPGeGDList* TPGeGDList::Reverse() { TPGeGDList *pPre = this,*pCur = Next(); while(pCur != NULL && pCur != this) { TPGeGDList* temp = pCur->Next(); pCur->SetNext(pPre); pPre->SetPre(pCur); pPre = pCur; pCur = temp; } if(pCur == NULL) { this->SetNext(NULL); pPre->SetPre(NULL); return pPre; } else { this->SetNext(pPre); pPre->SetPre(this); return this; } } #endif