//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TList 模板类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TList 声明 单向循环链表 // 支持自动分配,使用[]可以将其看作一个具有无限长度的链表,同时优化了链表的随机访问速度。 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #ifndef _TLIST_H_ #define _TLIST_H_ #ifndef _TTABLE_H_ #include "TTable.h" #endif #ifndef _TLISTNODE_H_ #include "TListNode.h" #endif template class TList:public TTable { public: TList(long initLength = 0); TList(const TTable&table); TList(const TList&table); TList&operator = (const TTable&table); TList&operator = (const TList&table); virtual ~TList(); //space manage //when newLength&list,long from = 0); //operato //稳定插入排序 virtual void Arrange(bool bIncrease = true); //稳定插入排序 virtual void Arrange(int (*cmp)(const T&,const T&)); //比TTable::Reverse快的多! virtual void ReverseList(); virtual void Rotate(long iFrom,long iTo); void Detach(); void DetachAfter(long i); void SplitAtCur(TList&list); void SplitAt(long i,TList&list); TListNode*GetCurPos() const; protected: //head node,not the first data node; TListNode*head; //last node,when is empty it is head node; TListNode*tail; //the node whose index is cur,when cur is -1,curPos is head. TListNode*curPos; virtual void Realloc(long newLength); }; template TList& TList::operator = (const TTable&table) { this->DeepCopy(table); return *this; } template TList& TList::operator = (const TList&table) { this->DeepCopy(table); return *this; } template void TList::Detach() { curPos = head; this->cur = -1; DetachAfterCur(); } template void TList::DetachAfter(long i) { MoveTo(i); DetachAfterCur(); } template void TList::SplitAtCur(TList&list) { list.Conbine(*this,this->cur); } template void TList::SplitAt(long i,TList&list) { MoveTo(i); SplitAtCur(list); } template TListNode* TList::GetCurPos() const { return curPos; } template void TList::DetachAfterCur() { curPos->next = head; tail = curPos; this->length = this->cur + 1; } template T& TList::GetCurData() { return curPos->data; } template void TList::SetCurData(const T&t) { curPos->data = t; } template void TList::Clear() { tail->next = NULL; TListNode*p = head->next; while(p != NULL) { TListNode *pn = p->next; delete p; p = pn; } curPos = tail = head->next = head; this->length = 0; this->cur = -1; } template const T* TList::GetFirst() const { return this->IsEmpty() ? NULL : (const T*)(head->next); } template const T* TList::GetLast() const { return this->IsEmpty() ? NULL : (const T*)tail; } template const T* TList::GetNext(const T*p) const { return (p == NULL || p == ((const T*)tail)) ? NULL : (const T*)(((const TListNode*)p)->next); } template const T*TList::GetPre(const T*p) const { if (p == NULL) { return NULL; } if (p == ((const T*)(head->next))) { return NULL; } else if (p == (const T*)(curPos->next)) { return (const T*)curPos; } long i = 0; for (const TListNode*pCur = head;iGetLength();i++,pCur = pCur->next) { if ((const T*)(pCur->next) == p) { return (const T*)pCur; } } return NULL; } template const T& TList::GetAt(long index) const { TListNode *p; if (index>this->cur) { p = curPos; for (long i = this->cur;inext); } else if (indexcur) { p = head; for (long i = -1;inext); } else { p = curPos; } return p->data; } template void TList::ReverseList() { if (this->length < 2) { return; } TListNode*p,*next = head->next,*pre = head; for (long i = 0;ilength;i++) { p = next; next = p->next; p->next = pre; pre = p; } p = head->next; head->next = tail; tail = p; } template void TList::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 = GetCurPos(); MoveTo(iNewZero); //形成环路 tail->next = head->next; //更新head head->next = curPos; this->cur = 0; //更新tail tail = newTail; tail->next = head; } } template void TList::Arrange(bool bIncrease) { if (this->GetLength() < 2) { return; } if (bIncrease) { MoveToFirst(); MoveToNext(); while(!this->IsBegin()) { T temp = GetCurData(); long i = this->GetCur(); TListNode*pos = GetCurPos(); MoveToFirst(); TListNode*pre = head; long preCur = -1; while(this->GetCur() < i) { if (GetCurData()>temp) { curPos = pre; this->cur = preCur; InsertAfterCur(temp); curPos = pos; this->cur = i+1; DelCur(); } else { preCur = this->GetCur(); pre = GetCurPos(); MoveToNext(); } } MoveToNext(); } } else { MoveToFirst(); MoveToNext(); while(!this->IsBegin()) { T temp = GetCurData(); long i = this->GetCur(); TListNode*pos = GetCurPos(); MoveToFirst(); TListNode*pre = head; long preCur = -1; while(this->GetCur()cur = preCur; InsertAfterCur(temp); curPos = pos; this->cur = i+1; DelCur(); } else { preCur = this->GetCur(); pre = GetCurPos(); MoveToNext(); } } MoveToNext(); } } } template void TList::Arrange(int (*cmp)(const T&,const T&)) { if (this->GetLength() < 2) { return; } MoveToFirst(); MoveToNext(); while(!this->IsBegin()) { T temp = GetCurData(); long i = this->GetCur(); TListNode*pos = GetCurPos(); MoveToFirst(); TListNode*pre = head; long preCur = -1; while(this->GetCur()0) { curPos = pre; this->cur = preCur; InsertAfterCur(temp); curPos = pos; this->cur = i+1; DelCur(); } else { preCur = this->GetCur(); pre = GetCurPos(); MoveToNext(); } } MoveToNext(); } } template void TList::MoveToFirst() { if (this->IsEmpty()) { curPos = head; this->cur = -1; } else { curPos = head->next; this->cur = 0; } } template void TList::MoveToLast() { curPos = tail; this->cur = this->length-1; } template void TList::MoveToPre() { if (this->GetCur() == -1) { MoveToLast(); } else { MoveTo(this->GetCur() - 1); } } template void TList::MoveToNext() { curPos = curPos->next; this->cur++; if (curPos == head) {//recycle this->cur = -1; } } template void TList::MoveTo(long index) { if (this->IsValidIndex(index)) { if (index == this->GetLastIndex()) { MoveToLast(); } else { if (index < this->cur) {//before MoveToFirst(); } while(this->GetCur() != index) { MoveToNext(); } } } else { this->cur = -1; curPos = head; } } template void TList::InsertAfterCur(const T&t) { TListNode*p = new TListNode; p->data = t; p->next = curPos->next; curPos->next = p; this->length++; this->cur++; if (curPos == tail) { tail = p; } curPos = p; } template void TList::InsertCur(const T&t) { MoveToPre(); InsertAfterCur(t); } template long TList::AddTail(const T&t) { MoveToLast(); InsertAfterCur(t); return this->GetLastIndex(); } template void TList::InsertHead(const T&t) { MoveTo(-1); InsertAfterCur(t); } template void TList::Insert(long index,const T&t) { MoveTo(index-1); InsertAfterCur(t); } template void TList::DelCur() { TListNode*p = curPos; MoveToPre(); curPos->next = p->next; if (p == tail) { tail = curPos; } delete p; this->length--; } template void TList::Realloc(long newLength) { if (newLength>this->GetLength()) { long oldCur = this->cur; TListNode*oldPos = curPos; T t; while(this->GetLength()cur = oldCur; } } template void TList::SetLength(long newLength,bool bCopy) { if (newLength>this->GetLength()) { Realloc(newLength); } else { while(newLengthGetLength()) { this->DelTail(); } } } template TList::TList(long initLength) { head = tail = new TListNode; head->next = head; curPos = head; Realloc(initLength); } template TList::TList(const TTable&table) { head = tail = new TListNode; head->next = head; curPos = head; this->DeepCopy(table); } template TList::TList(const TList&table) { head = tail = new TListNode; head->next = head; curPos = head; this->DeepCopy(table); } template TList::~TList() { if (head == NULL) { return; } Clear(); delete head; } template long TList::Conbine(TList&lstConbine,long from) { if (lstConbine.IsValidIndex(from)) { long oldCur = this->GetCur(); TListNode* oldPos = GetCurPos(); lstConbine.MoveTo(from); tail->next = lstConbine.GetCurPos(); lstConbine.MoveToLast(); tail = lstConbine.GetCurPos(); this->length += lstConbine.GetLength() - from; lstConbine.DetachAfter(from- 1); tail->next = head; this->cur = oldCur; curPos = oldPos; } return this->length; } #endif