Files
envi-code/SourceCode/Code2026/inc/AdsXRx/List.h
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

661 lines
12 KiB
C++

//-------------------------------------------------------------------------------------------------------+
// 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 T> class List:public Table<T>
{
public:
List(long initLength = 0);
List(const Table<T>&table);
List(const List<T>&table);
List<T>&operator = (const Table<T>&table);
List<T>&operator = (const List<T>&table);
virtual ~List();
//space manage
//when newLength<old this->length,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<T>&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<T>&list);
void SplitAt(long i,List<T>&list);
ListNode<T>*GetCurPos() const;
protected:
//head node,not the first data node;
ListNode<T>*head;
//last node,when is empty it is head node;
ListNode<T>*tail;
//the node whose index is this->cur,when this->cur is -1,curPos is head.
ListNode<T>*curPos;
virtual void Realloc(long newLength);
};
template<class T>
List<T>& List<T>::operator = (const Table<T>&table)
{
this->DeepCopy(table);
return *this;
}
template<class T>
List<T>& List<T>::operator = (const List<T>&table)
{
this->DeepCopy(table);
return *this;
}
template<class T>
void List<T>::Detach()
{
this->curPos = this->head;
this->cur = -1;
DetachAfterCur();
}
template<class T>
void List<T>::DetachAfter(long i)
{
MoveTo(i);
DetachAfterCur();
}
template<class T>
void List<T>::SplitAtCur(List<T>&list)
{
list.Conbine(*this,this->cur);
}
template<class T>
void List<T>::SplitAt(long i,List<T>&list)
{
MoveTo(i);
SplitAtCur(list);
}
template<class T>
ListNode<T>* List<T>::GetCurPos() const
{
return this->curPos;
}
template<class T>
void List<T>::DetachAfterCur()
{
this->curPos->next =this-> head;
this->tail = this->curPos;
this->length = this->cur + 1;
}
template<class T>
T& List<T>::GetCurData()
{
return this->curPos->data;
}
template<class T>
void List<T>::SetCurData(const T&t)
{
this->curPos->data = t;
}
template<class T>
void List<T>::Clear()
{
this->tail->next = NULL;
ListNode<T>*p = this->head->next;
while(p != NULL)
{
ListNode<T> *pn = p->next;
delete p;
p = pn;
}
this->curPos = this->tail = this->head->next = this->head;
this->length = 0;
this->cur = -1;
}
template<class T>
const T* List<T>::GetFirst() const
{
return this->IsEmpty() ? NULL : (const T*)(this->head->next);
}
template<class T>
const T* List<T>::GetLast() const
{
return this->IsEmpty() ? NULL : (const T*)this->tail;
}
template<class T>
const T* List<T>::GetNext(const T*p) const
{
return (p == NULL || p == ((const T*)this->tail)) ? NULL : (const T*)(((const ListNode<T>*)p)->next);
}
template<class T>
const T*List<T>::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<T>*pCur = this->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& List<T>::GetAt(long index) const
{
ListNode<T> *p;
if (index>this->cur)
{
p = this->curPos;
for (long i = this->cur;i<index;i++,p = p->next);
}
else if (index<this->cur)
{
p = this->head;
for (long i = -1;i<index;i++,p = p->next);
}
else
{
p = this->curPos;
}
return p->data;
}
template<class T>
void List<T>::ReverseList()
{
if (this->length < 2)
{
return;
}
ListNode<T>*p,*next = this->head->next,*pre = this->head;
for (long i = 0;i<this->length;i++)
{
p = next;
next = p->next;
p->next = pre;
pre = p;
}
p = this->head->next;
this->head->next = this->tail;
this->tail = p;
}
template<class T>
void List<T>::Rotate(long iFrom,long iTo)
{
if (iFrom != iTo)
{
long iNewZero = (iFrom - iTo + this->GetLength()) % this->GetLength();
MoveTo(iNewZero - 1 + this->GetLength() % this->GetLength());
ListNode<T>*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<class T>
void List<T>::Arrange(bool bIncrease)
{
if (this->GetLength() < 2)
{
return;
}
if (bIncrease)
{
MoveToFirst();
MoveToNext();
while(!this->IsBegin())
{
T temp = GetCurData();
long i = this->GetCur();
ListNode<T>*pos = GetCurPos();
MoveToFirst();
ListNode<T>*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<T>*pos = GetCurPos();
MoveToFirst();
ListNode<T>*pre = 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();
}
}
}
template<class T>
void List<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();
ListNode<T>*pos = GetCurPos();
MoveToFirst();
ListNode<T>*pre = head;
long preCur = -1;
while(this->GetCur()<i)
{
if (cmp(GetCurData(),temp)>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<class T>
void List<T>::MoveToFirst()
{
if (this->IsEmpty())
{
this->curPos = this->head;
this->cur = -1;
}
else
{
this->curPos = this->head->next;
this->cur = 0;
}
}
template<class T>
void List<T>::MoveToLast()
{
this->curPos = this->tail;
this->cur = this->length-1;
}
template<class T>
void List<T>::MoveToPre()
{
if (this->GetCur() == -1)
{
MoveToLast();
}
else
{
MoveTo(this->GetCur() - 1);
}
}
template<class T>
void List<T>::MoveToNext()
{
this->curPos = this->curPos->next;
this->cur++;
if (this->curPos == this->head)
{//recycle
this->cur = -1;
}
}
template<class T>
void List<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;
this->curPos = this->head;
}
}
template<class T>
void List<T>::InsertAfterCur(const T&t)
{
ListNode<T>*p = new ListNode<T>;
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<class T>
void List<T>::InsertCur(const T&t)
{
MoveToPre();
InsertAfterCur(t);
}
template<class T>
long List<T>::AddTail(const T&t)
{
MoveToLast();
InsertAfterCur(t);
return this->GetLastIndex();
}
template<class T>
void List<T>::InsertHead(const T&t)
{
MoveTo(-1);
InsertAfterCur(t);
}
template<class T>
void List<T>::Insert(long index,const T&t)
{
MoveTo(index-1);
InsertAfterCur(t);
}
template<class T>
void List<T>::DelCur()
{
ListNode<T>*p = this->curPos;
MoveToPre();
this->curPos->next = p->next;
if (p == tail)
{
this->tail = this->curPos;
}
delete p;
this->length--;
}
template<class T>
void List<T>::Realloc(long newLength)
{
if (newLength>this->GetLength())
{
long oldCur = this->cur;
ListNode<T>*oldPos = this->curPos;
T t;
while(this->GetLength()<newLength)
{
AddTail(t);
}
this->curPos = oldPos;
this->cur = oldCur;
}
}
template<class T>
void List<T>::SetLength(long newLength,bool bCopy)
{
if (newLength>this->GetLength())
{
Realloc(newLength);
}
else
{
while(newLength<this->GetLength())
{
this->DelTail();
}
}
}
template<class T>
List<T>::List(long initLength)
{
this->head = this->tail = new ListNode<T>;
this->head->next = this->head;
this->curPos = this->head;
Realloc(initLength);
}
template<class T>
List<T>::List(const Table<T>&table)
{
this->head = this->tail = new ListNode<T>;
this->head->next = this->head;
this->curPos = this->head;
this->DeepCopy(table);
}
template<class T>
List<T>::List(const List<T>&table)
{
this->head = this->tail = new ListNode<T>;
this->head->next = this->head;
this->curPos = this->head;
this->DeepCopy(table);
}
template<class T>
List<T>::~List()
{
if (this->head == NULL)
{
return;
}
Clear();
delete this->head;
}
template<class T>
long List<T>::Conbine(List<T>&list,long from)
{
if (list.IsValidIndex(from))
{
long oldCur = this->GetCur();
ListNode<T>* 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