#pragma once #include "SHTable.h" #include "SHListNode.h" template class SHTable; template class SHList:public SHTable { public: SHList(long initLength = 0); SHList(const SHTable&table); SHList(const SHList&table); SHList&operator = (const SHTable&table); SHList&operator = (const SHList&table); virtual ~SHList(); //space manage //when newLength&list,long from = 0); //operato //稳定插入排序 virtual void Arrange(bool bIncrease = true); //稳定插入排序 virtual void Arrange(int (*cmp)(const T&,const T&)); //比SHTable::Reverse快的多! virtual void ReverseList(); virtual void Rotate(long iFrom,long iTo); void Detach(); void DetachAfter(long i); void SplitAtCur(SHList&list); void SplitAt(long i,SHList&list); SHListNode*GetCurPos() const; protected: //head node,not the first data node; SHListNode*head; //last node,when is empty it is head node; SHListNode*tail; //the node whose index is cur,when cur is -1,curPos is head. SHListNode*curPos; virtual void Realloc(long newLength); }; template SHList& SHList::operator = (const SHTable&table) { DeepCopy(table); return *this; } template SHList& SHList::operator = (const SHList&table) { DeepCopy(table); return *this; } template void SHList::Detach() { curPos = head; this->cur = -1; DetachAfterCur(); } template void SHList::DetachAfter(long i) { MoveTo(i); DetachAfterCur(); } template void SHList::SplitAtCur(SHList&list) { list.Conbine(*this,this->cur); } template void SHList::SplitAt(long i,SHList&list) { MoveTo(i); SplitAtCur(list); } template SHListNode* SHList::GetCurPos() const { return curPos; } template void SHList::DetachAfterCur() { curPos->next = head; tail = curPos; this->length = this->cur + 1; } template T& SHList::GetCurData() { return curPos->data; } template void SHList::SetCurData(const T&t) { curPos->data = t; } template void SHList::Clear() { tail->next = NULL; SHListNode*p = head->next; while(p != NULL) { SHListNode *pn = p->next; delete p; p = pn; } curPos = tail = head->next = head; this->length = 0; this->cur = -1; } template const T* SHList::GetFirst() const { return this->IsEmpty() ? NULL : (const T*)(head->next); } template const T* SHList::GetLast() const { return this->IsEmpty() ? NULL : (const T*)tail; } template const T* SHList::GetNext(const T*p) const { return (p == NULL || p == ((const T*)tail)) ? NULL : (const T*)(((const SHListNode*)p)->next); } template const T*SHList::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 SHListNode*pCur = head;iGetLength();i++,pCur = pCur->next) { if ((const T*)(pCur->next) == p) { return (const T*)pCur; } } return NULL; } template const T& SHList::GetAt(long index) const { SHListNode *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 SHList::ReverseList() { if (this->length < 2) { return; } SHListNode*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 SHList::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 = GetCurPos(); MoveTo(iNewZero); //形成环路 tail->next = head->next; //更新head head->next = curPos; this->cur = 0; //更新tail tail = newTail; tail->next = head; } } template void SHList::Arrange(bool bIncrease) { if (this->GetLength() < 2) { return; } if (bIncrease) { MoveToFirst(); MoveToNext(); while(!this->IsBegin()) { T temp = GetCurData(); long i = this->GetCur(); SHListNode*pos = GetCurPos(); MoveToFirst(); SHListNode*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(); SHListNode*pos = GetCurPos(); MoveToFirst(); SHListNode*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 SHList::Arrange(int (*cmp)(const T&,const T&)) { if (this->GetLength() < 2) { return; } MoveToFirst(); MoveToNext(); while(!this->IsBegin()) { T temp = GetCurData(); long i = this->GetCur(); SHListNode*pos = GetCurPos(); MoveToFirst(); SHListNode*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 SHList::MoveToFirst() { if (this->IsEmpty()) { curPos = head; this->cur = -1; } else { curPos = head->next; this->cur = 0; } } template void SHList::MoveToLast() { curPos = tail; this->cur = this->length-1; } template void SHList::MoveToPre() { if (this->GetCur() == -1) { MoveToLast(); } else { MoveTo(this->GetCur() - 1); } } template void SHList::MoveToNext() { curPos = curPos->next; this->cur++; if (curPos == head) {//recycle this->cur = -1; } } template void SHList::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 SHList::InsertAfterCur(const T&t) { SHListNode*p = new SHListNode; p->data = t; p->next = curPos->next; curPos->next = p; this->length++; this->cur++; if (curPos == tail) { tail = p; } curPos = p; } template void SHList::InsertCur(const T&t) { MoveToPre(); InsertAfterCur(t); } template long SHList::AddTail(const T&t) { MoveToLast(); InsertAfterCur(t); return this->GetLastIndex(); } template void SHList::InsertHead(const T&t) { MoveTo(-1); InsertAfterCur(t); } template void SHList::Insert(long index,const T&t) { MoveTo(index-1); InsertAfterCur(t); } template void SHList::DelCur() { SHListNode*p = curPos; MoveToPre(); curPos->next = p->next; if (p == tail) { tail = curPos; } delete p; this->length--; } template void SHList::Realloc(long newLength) { if (newLength>this->GetLength()) { long oldCur = this->cur; SHListNode*oldPos = curPos; T t; while(this->GetLength()cur = oldCur; } } template void SHList::SetLength(long newLength,bool bCopy) { if (newLength>this->GetLength()) { Realloc(newLength); } else { while(newLengthGetLength()) { this->DelTail(); } } } template SHList::SHList(long initLength) { head = tail = new SHListNode; head->next = head; curPos = head; Realloc(initLength); } template SHList::SHList(const SHTable&table) { head = tail = new SHListNode; head->next = head; curPos = head; DeepCopy(table); } template SHList::SHList(const SHList&table) { head = tail = new SHListNode; head->next = head; curPos = head; DeepCopy(table); } template SHList::~SHList() { if (head == NULL) { return; } Clear(); delete head; } template long SHList::Conbine(SHList&lstConbine,long from) { if (lstConbine.IsValidIndex(from)) { long oldCur = this->GetCur(); SHListNode* 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; }