#pragma once #include "SHList.h" #include "SHTable.h" #include "DListNode.h" template class DualPtrList : public SHList< T > { public: DualPtrList(long initLength = 0); DualPtrList(const SHTable& table); DualPtrList(const DualPtrList& table); DualPtrList&operator =(const DualPtrList& table); DualPtrList&operator =(const SHTable& table); virtual ~DualPtrList(); 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(SHList& 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 DualPtrList& DualPtrList::operator = (const DualPtrList& table) { DeepCopy(table); return *this; } template DualPtrList& DualPtrList::operator = (const SHTable& table) { DeepCopy(table); return *this; } template void DualPtrList::Clear() { this->tail->next = NULL; DListNode*p = (DListNode*)(this->head->next); while(p != NULL) { DListNode *pn = (DListNode*)(p->next); delete p; p = pn; } this->curPos = this->tail = this->head->next = this->head; ((DListNode*)this->head)->pre = this->head; this->length = 0; this->cur = -1; } template const T* DualPtrList::GetPre(const T*p)const { return (p == NULL || p == ((const T*)(this->head->next))) ? NULL : (const T*)(((const DListNode*)p)->pre); } template const T& DualPtrList::GetAt(long index)const { SHListNode*p = this->curPos; long i = this->cur; for (; i < index; i++, p = p->next) { ; } for (; i > index; i--, p = ((DListNode*)p)->pre) { ; } return p->data; } template void DualPtrList::ReverseList() { if (this->length < 2) { return; } SHListNode*p,*next = this->head->next,*pre = this->head; for (long i = 0; i < this->length; i++) { p = next; next = p->next; p->next = pre; ((DListNode*)pre)->pre = p; pre = p; } p = this->head->next; this->head->next = this->tail; ((DListNode*)this->tail)->pre = this->head; this->tail = p; } template void DualPtrList::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(); SHListNode* 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(); SHListNode*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 DualPtrList::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(); SHListNode* 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 DualPtrList::InsertAfterCur(const T& t) { DListNode* p = new DListNode; p->data = t; p->next = this->curPos->next; this->curPos->next = p; p->pre = this->curPos; ((DListNode*)(p->next))->pre = p; this->length++; this->cur++; if (this->curPos == this->tail) { this->tail = p; } this->curPos = p; } template void DualPtrList::DelCur() { DListNode* p = (DListNode*)this->curPos; MoveToPre(); this->curPos->next = p->next; ((DListNode*)(p->next))->pre = this->curPos; if (p == this->tail) { this->tail = this->curPos; } delete p; this->length--; } template DualPtrList::DualPtrList(long initLength) { delete this->head; this->head = this->tail = new DListNode; this->head->next = this->head; ((DListNode*)this->head)->pre = this->head; this->curPos = this->head; this->Realloc(initLength); } template DualPtrList::DualPtrList(const SHTable&table) { delete this->head; this->head = this->tail = new DListNode; this->head->next = this->head; ((DListNode*)this->head)->pre = this->head; this->curPos = this->head; DeepCopy(table); } template DualPtrList::DualPtrList(const DualPtrList&table) { delete this->head; this->head = this->tail = new DListNode; this->head->next = this->head; ((DListNode*)this->head)->pre = this->head; this->curPos = this->head; DeepCopy(table); } template DualPtrList::~DualPtrList() { if (this->head == NULL) { return; } Clear(); DListNode* p = (DListNode*)this->head; delete p; this->head = NULL; } template void DualPtrList::MoveToPre() { this->curPos = ((DListNode*)this->curPos)->pre; this->cur--; if (this->curPos == this->tail) { this->cur = this->length - 1; } } template void DualPtrList::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 DualPtrList::Conbine(SHList&lstConbine,long from) { if (lstConbine.IsValidIndex(from)) { SHListNode*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; ((DListNode*)first)->pre = this->tail; this->tail = last; this->tail->next = this->head; ((DListNode*)this->head)->pre = this->tail; } return this->length; } template void DualPtrList::Rotate(long iFrom,long iTo) { if (iFrom != iTo) { long iNewZero = (iFrom - iTo + this->GetLength()) % this->GetLength(); MoveTo(iNewZero - 1 + this->GetLength() % this->GetLength()); SHListNode* newTail = this->GetCurPos(); MoveTo(iNewZero); //形成环路 this->tail->next = this->head->next; ((DListNode*)this->head->next)->pre = this->tail; //更新this->head this->head->next = this->curPos; ((DListNode*)this->curPos)->pre = this->head; this->cur = 0; //更新tail this->tail = newTail; this->tail->next = this->head; ((DListNode*)this->head)->pre = this->tail; } } template void DualPtrList::DetachAfterCur() { this->curPos->next = this->head; ((DListNode*)this->head)->pre = this->curPos; this->tail = this->curPos; this->length = this->cur + 1; }