Files
envi-code/SourceCode/Code2026/Dimension/SHList.h
T
2026-09-28 15:28:50 +08:00

643 lines
10 KiB
C++

#pragma once
#include "SHTable.h"
#include "SHListNode.h"
template<class T> class SHTable;
template<class T> class SHList:public SHTable<T>
{
public:
SHList(long initLength = 0);
SHList(const SHTable<T>&table);
SHList(const SHList<T>&table);
SHList<T>&operator = (const SHTable<T>&table);
SHList<T>&operator = (const SHList<T>&table);
virtual ~SHList();
//space manage
//when newLength<old length,cur will move to last!always copy!
virtual void SetLength(long newLength,bool bCopy = true);
//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 cur == -1,insert first node;quick speed!
virtual void InsertAfterCur(const T&t);
//alloc cur == -1!slow speed!
virtual void InsertCur(const T&t);
//if cur != -1,don't change cur;if cur == -1,AddTail(T&t),cur move to last!
//if index == 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);
//cur node can't be head node!!!
virtual void DelCur();
virtual void Clear();
//detach but not release
virtual void DetachAfterCur();
virtual long Conbine(SHList<T>&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<T>&list);
void SplitAt(long i,SHList<T>&list);
SHListNode<T>*GetCurPos() const;
protected:
//head node,not the first data node;
SHListNode<T>*head;
//last node,when is empty it is head node;
SHListNode<T>*tail;
//the node whose index is cur,when cur is -1,curPos is head.
SHListNode<T>*curPos;
virtual void Realloc(long newLength);
};
template<class T>
SHList<T>& SHList<T>::operator = (const SHTable<T>&table)
{
DeepCopy(table);
return *this;
}
template<class T>
SHList<T>& SHList<T>::operator = (const SHList<T>&table)
{
DeepCopy(table);
return *this;
}
template<class T>
void SHList<T>::Detach()
{
curPos = head;
this->cur = -1;
DetachAfterCur();
}
template<class T>
void SHList<T>::DetachAfter(long i)
{
MoveTo(i);
DetachAfterCur();
}
template<class T>
void SHList<T>::SplitAtCur(SHList<T>&list)
{
list.Conbine(*this,this->cur);
}
template<class T>
void SHList<T>::SplitAt(long i,SHList<T>&list)
{
MoveTo(i);
SplitAtCur(list);
}
template<class T>
SHListNode<T>* SHList<T>::GetCurPos() const
{
return curPos;
}
template<class T>
void SHList<T>::DetachAfterCur()
{
curPos->next = head;
tail = curPos;
this->length = this->cur + 1;
}
template<class T>
T& SHList<T>::GetCurData()
{
return curPos->data;
}
template<class T>
void SHList<T>::SetCurData(const T&t)
{
curPos->data = t;
}
template<class T>
void SHList<T>::Clear()
{
tail->next = NULL;
SHListNode<T>*p = head->next;
while(p != NULL)
{
SHListNode<T> *pn = p->next;
delete p;
p = pn;
}
curPos = tail = head->next = head;
this->length = 0;
this->cur = -1;
}
template<class T>
const T* SHList<T>::GetFirst() const
{
return this->IsEmpty() ? NULL : (const T*)(head->next);
}
template<class T>
const T* SHList<T>::GetLast() const
{
return this->IsEmpty() ? NULL : (const T*)tail;
}
template<class T>
const T* SHList<T>::GetNext(const T*p) const
{
return (p == NULL || p == ((const T*)tail)) ? NULL : (const T*)(((const SHListNode<T>*)p)->next);
}
template<class T>
const T*SHList<T>::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<T>*pCur = head;i<this->GetLength();i++,pCur = pCur->next)
{
if ((const T*)(pCur->next) == p)
{
return (const T*)pCur;
}
}
return NULL;
}
template<class T>
const T& SHList<T>::GetAt(long index) const
{
SHListNode<T> *p;
if (index>this->cur)
{
p = curPos;
for (long i = this->cur;i<index;i++,p = p->next);
}
else if (index<this->cur)
{
p = head;
for (long i = -1;i<index;i++,p = p->next);
}
else
{
p = curPos;
}
return p->data;
}
template<class T>
void SHList<T>::ReverseList()
{
if (this->length < 2)
{
return;
}
SHListNode<T>*p,*next = head->next,*pre = head;
for (long i = 0;i<this->length;i++)
{
p = next;
next = p->next;
p->next = pre;
pre = p;
}
p = head->next;
head->next = tail;
tail = p;
}
template<class T>
void SHList<T>::Rotate(long iFrom,long iTo)
{
if (iFrom != iTo)
{
long iNewZero = (iFrom - iTo + this->GetLength()) % this->GetLength();
MoveTo(iNewZero - 1 + this->GetLength() % this->GetLength());
SHListNode<T>*newTail = GetCurPos();
MoveTo(iNewZero);
//形成环路
tail->next = head->next;
//更新head
head->next = curPos;
this->cur = 0;
//更新tail
tail = newTail;
tail->next = head;
}
}
template<class T>
void SHList<T>::Arrange(bool bIncrease)
{
if (this->GetLength() < 2)
{
return;
}
if (bIncrease)
{
MoveToFirst();
MoveToNext();
while(!this->IsBegin())
{
T temp = GetCurData();
long i = this->GetCur();
SHListNode<T>*pos = GetCurPos();
MoveToFirst();
SHListNode<T>*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<T>*pos = GetCurPos();
MoveToFirst();
SHListNode<T>*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();
}
}
}
template<class T>
void SHList<T>::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<T>*pos = GetCurPos();
MoveToFirst();
SHListNode<T>*pre = head;
long preCur = -1;
while(this->GetCur()<i)
{
if (cmp(GetCurData(),temp)>0)
{
curPos = pre;
this->cur = preCur;
InsertAfterCur(temp);
curPos = pos;
this->cur = i+1;
DelCur();
}
else
{
preCur = this->GetCur();
pre = GetCurPos();
MoveToNext();
}
}
MoveToNext();
}
}
template<class T>
void SHList<T>::MoveToFirst()
{
if (this->IsEmpty())
{
curPos = head;
this->cur = -1;
}
else
{
curPos = head->next;
this->cur = 0;
}
}
template<class T>
void SHList<T>::MoveToLast()
{
curPos = tail;
this->cur = this->length-1;
}
template<class T>
void SHList<T>::MoveToPre()
{
if (this->GetCur() == -1)
{
MoveToLast();
}
else
{
MoveTo(this->GetCur() - 1);
}
}
template<class T>
void SHList<T>::MoveToNext()
{
curPos = curPos->next;
this->cur++;
if (curPos == head)
{//recycle
this->cur = -1;
}
}
template<class T>
void SHList<T>::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<class T>
void SHList<T>::InsertAfterCur(const T&t)
{
SHListNode<T>*p = new SHListNode<T>;
p->data = t;
p->next = curPos->next;
curPos->next = p;
this->length++;
this->cur++;
if (curPos == tail)
{
tail = p;
}
curPos = p;
}
template<class T>
void SHList<T>::InsertCur(const T&t)
{
MoveToPre();
InsertAfterCur(t);
}
template<class T>
long SHList<T>::AddTail(const T&t)
{
MoveToLast();
InsertAfterCur(t);
return this->GetLastIndex();
}
template<class T>
void SHList<T>::InsertHead(const T&t)
{
MoveTo(-1);
InsertAfterCur(t);
}
template<class T>
void SHList<T>::Insert(long index,const T&t)
{
MoveTo(index-1);
InsertAfterCur(t);
}
template<class T>
void SHList<T>::DelCur()
{
SHListNode<T>*p = curPos;
MoveToPre();
curPos->next = p->next;
if (p == tail)
{
tail = curPos;
}
delete p;
this->length--;
}
template<class T>
void SHList<T>::Realloc(long newLength)
{
if (newLength>this->GetLength())
{
long oldCur = this->cur;
SHListNode<T>*oldPos = curPos;
T t;
while(this->GetLength()<newLength)
{
AddTail(t);
}
curPos = oldPos;
this->cur = oldCur;
}
}
template<class T>
void SHList<T>::SetLength(long newLength,bool bCopy)
{
if (newLength>this->GetLength())
{
Realloc(newLength);
}
else
{
while(newLength<this->GetLength())
{
this->DelTail();
}
}
}
template<class T>
SHList<T>::SHList(long initLength)
{
head = tail = new SHListNode<T>;
head->next = head;
curPos = head;
Realloc(initLength);
}
template<class T>
SHList<T>::SHList(const SHTable<T>&table)
{
head = tail = new SHListNode<T>;
head->next = head;
curPos = head;
DeepCopy(table);
}
template<class T>
SHList<T>::SHList(const SHList<T>&table)
{
head = tail = new SHListNode<T>;
head->next = head;
curPos = head;
DeepCopy(table);
}
template<class T>
SHList<T>::~SHList()
{
if (head == NULL)
{
return;
}
Clear();
delete head;
}
template<class T>
long SHList<T>::Conbine(SHList<T>&lstConbine,long from)
{
if (lstConbine.IsValidIndex(from))
{
long oldCur = this->GetCur();
SHListNode<T>* 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;
}