//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TDualPtrList 模板类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TDualPtrList 声明 双向循环链表,提高了单向链表反向遍历和随机访问的速度 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #ifndef _TDUALPTRLIST_H_ #define _TDUALPTRLIST_H_ #ifndef _TLIST_H_ #include "TList.h" #endif #ifndef _TTABLE_H_ #include "TTable.h" #endif #ifndef _TDLISTNODE_H_ #include "TDListNode.h" #endif template class TDualPtrList : public TList< T > { public: TDualPtrList(long initLength = 0); TDualPtrList(const TTable& table); TDualPtrList(const TDualPtrList& table); TDualPtrList&operator =(const TDualPtrList& table); TDualPtrList&operator =(const TTable& table); virtual ~TDualPtrList(); virtual const T& GetAt(long index)const; virtual const T* GetPre(const T* p)const; virtual void MoveTo(long index); virtual void MoveToPre(); virtual void InsertAfterCur(const T& t); virtual void DelCur(); virtual void Clear(); virtual void DetachAfterCur(); virtual long Conbine(TList& list, long from = 0); virtual void Arrange(bool bIncrease = true); virtual void Arrange(int (*cmp)(const T&,const T&)); virtual void ReverseList(); virtual void Rotate(long iFrom, long iTo); }; template TDualPtrList& TDualPtrList::operator = (const TDualPtrList& table) { this->DeepCopy(table); return *this; } template TDualPtrList& TDualPtrList::operator = (const TTable& table) { this->DeepCopy(table); return *this; } template void TDualPtrList::Clear() { this->tail->next = NULL; TDListNode*p = (TDListNode*)(this->head->next); while(p != NULL) { TDListNode *pn = (TDListNode*)(p->next); delete p; p = pn; } this->curPos = this->tail = this->head->next = this->head; ((TDListNode*)this->head)->pre = this->head; this->length = 0; this->cur = -1; } template const T* TDualPtrList::GetPre(const T*p)const { return (p == NULL || p == ((const T*)(this->head->next))) ? NULL : (const T*)(((const TDListNode*)p)->pre); } template const T& TDualPtrList::GetAt(long index)const { TListNode*p = this->curPos; long i = this->cur; for (; i < index; i++, p = p->next) { ; } for (; i > index; i--, p = ((TDListNode*)p)->pre) { ; } return p->data; } template void TDualPtrList::ReverseList() { if (this->length < 2) { return; } TListNode*p,*next = this->head->next,*pre = this->head; for (long i = 0; i < this->length; i++) { p = next; next = p->next; p->next = pre; ((TDListNode*)pre)->pre = p; pre = p; } p = this->head->next; this->head->next = this->tail; ((TDListNode*)this->tail)->pre = this->head; this->tail = p; } template void TDualPtrList::Arrange(bool bIncrease) { if (this->GetLength() < 2) { return; } if (bIncrease) { this->MoveToFirst(); this->MoveToNext(); while(!this->IsBegin()) { T temp = this->GetCurData(); long i = this->GetCur(); TListNode* pos = this->GetCurPos(); MoveToPre(); if (this->GetCurData() > temp) { while(!this->IsBegin() && this->GetCurData() > temp) { MoveToPre(); } InsertAfterCur(temp); this->curPos = pos; this->cur = i + 1; DelCur(); } else { this->MoveToNext(); } this->MoveToNext(); } } else { this->MoveToFirst(); this->MoveToNext(); while(!this->IsBegin()) { T temp = this->GetCurData(); long i = this->GetCur(); TListNode*pos = this->GetCurPos(); MoveToPre(); if (this->GetCurData() < temp) { while(!this->IsBegin() && this->GetCurData() < temp) { MoveToPre(); } InsertAfterCur(temp); this->curPos = pos; this->cur = i + 1; DelCur(); } else { this->MoveToNext(); } this->MoveToNext(); } } } template void TDualPtrList::Arrange(int (*cmp)(const T&,const T&)) { if (this->GetLength() < 2) { return; } this->MoveToFirst(); this->MoveToNext(); while(!this->IsBegin()) { T temp = this->GetCurData(); long i = this->GetCur(); TListNode* pos = this->GetCurPos(); MoveToPre(); if (cmp(this->GetCurData(),temp) > 0) { while(!this->IsBegin() && cmp(this->GetCurData(),temp) > 0) { MoveToPre(); } InsertAfterCur(temp); this->curPos = pos; this->cur = i + 1; DelCur(); } else { this->MoveToNext(); } this->MoveToNext(); } } template void TDualPtrList::InsertAfterCur(const T& t) { TDListNode* p = new TDListNode; p->data = t; p->next = this->curPos->next; this->curPos->next = p; p->pre = this->curPos; ((TDListNode*)(p->next))->pre = p; this->length++; this->cur++; if (this->curPos == this->tail) { this->tail = p; } this->curPos = p; } template void TDualPtrList::DelCur() { TDListNode* p = (TDListNode*)this->curPos; MoveToPre(); this->curPos->next = p->next; ((TDListNode*)(p->next))->pre = this->curPos; if (p == this->tail) { this->tail = this->curPos; } delete p; this->length--; } template TDualPtrList::TDualPtrList(long initLength) { delete this->head; this->head = this->tail = new TDListNode; this->head->next = this->head; ((TDListNode*)this->head)->pre = this->head; this->curPos = this->head; this->Realloc(initLength); } template TDualPtrList::TDualPtrList(const TTable&table) { delete this->head; this->head = this->tail = new TDListNode; this->head->next = this->head; ((TDListNode*)this->head)->pre = this->head; this->curPos = this->head; this->DeepCopy(table); } template TDualPtrList::TDualPtrList(const TDualPtrList&table) { delete this->head; this->head = this->tail = new TDListNode; this->head->next = this->head; ((TDListNode*)this->head)->pre = this->head; this->curPos = this->head; this->DeepCopy(table); } template TDualPtrList::~TDualPtrList() { if (this->head == NULL) { return; } Clear(); TDListNode* p = (TDListNode*)this->head; delete p; this->head = NULL; } template void TDualPtrList::MoveToPre() { this->curPos = ((TDListNode*)this->curPos)->pre; this->cur--; if (this->curPos == this->tail) { this->cur = this->length - 1; } } template void TDualPtrList::MoveTo(long index) { if (this->IsValidIndex(index)) { if (index == 0) { this->curPos = this->head->next; this->cur = 0; } else if (index == this->GetLastIndex()) { this->curPos = this->tail; this->cur = index; } else if (index >= this->cur) { while(this->GetCur() != index) { this->MoveToNext(); } } else { while(this->GetCur() != index) { MoveToPre(); } } } else { this->cur = -1; this->curPos = this->head; } } template long TDualPtrList::Conbine(TList&lstConbine,long from) { if (lstConbine.IsValidIndex(from)) { TListNode*first, *last; lstConbine.MoveTo(from); first = lstConbine.GetCurPos(); lstConbine.MoveToLast(); last = lstConbine.GetCurPos(); this->length += lstConbine.GetLength() - from; lstConbine.DetachAfter(from - 1); this->tail->next = first; ((TDListNode*)first)->pre = this->tail; this->tail = last; this->tail->next = this->head; ((TDListNode*)this->head)->pre = this->tail; } return this->length; } template void TDualPtrList::Rotate(long iFrom,long iTo) { if (iFrom != iTo) { long iNewZero = (iFrom - iTo + this->GetLength()) % this->GetLength(); MoveTo(iNewZero - 1 + this->GetLength() % this->GetLength()); TListNode* newTail = this->GetCurPos(); MoveTo(iNewZero); //形成环路 this->tail->next = this->head->next; ((TDListNode*)this->head->next)->pre = this->tail; //更新this->head this->head->next = this->curPos; ((TDListNode*)this->curPos)->pre = this->head; this->cur = 0; //更新tail this->tail = newTail; this->tail->next = this->head; ((TDListNode*)this->head)->pre = this->tail; } } template void TDualPtrList::DetachAfterCur() { this->curPos->next = this->head; ((TDListNode*)this->head)->pre = this->curPos; this->tail = this->curPos; this->length = this->cur + 1; } #endif