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