Files
envi-code/SourceCode/Code2026/inc/AdsXRx/DualList.h
T
2026-09-28 15:28:50 +08:00

422 lines
8.1 KiB
C++

//-------------------------------------------------------------------------------------------------------+
// Copyright (C), 1998-2007, SH Software Co. Ltd.
// = FileName : DualList 模板类
// = Version : ver2.0
// = Author : zjq
// = CreateDate : 2002-09-09
// = Description: DualList 声明 双向循环链表,提高了单向链表反向遍历和随机访问的速度
// = Maintainers:
//
//-------------------------------------------------------------------------------------------------------+
#ifndef _DUALLIST_H_
#define _DUALLIST_H_
#ifndef _LIST_H_
#include "List.h"
#endif
#ifndef _TABLE_H_
#include "Table.h"
#endif
#ifndef _DLISTNODE_H_
#include "DListNode.h"
#endif
template<class T> class DualList : public List< T >
{
public:
DualList(long initLength = 0);
DualList(const Table<T>& table);
DualList(const DualList<T>& table);
DualList<T>&operator =(const DualList<T>& table);
DualList<T>&operator =(const Table<T>& table);
virtual ~DualList();
virtual const T& GetAt(long index)const;
virtual const T* GetPre(const T* p)const;
virtual void MoveTo(long index);
virtual void MoveToPre();
virtual void InsertAfterCur(const T& t);
virtual void DelCur();
virtual void Clear();
virtual void DetachAfterCur();
virtual long Conbine(List<T>& list, long from = 0);
virtual void Arrange(bool bIncrease = true);
virtual void Arrange(int (*cmp)(const T&,const T&));
virtual void ReverseList();
virtual void Rotate(long iFrom, long iTo);
};
template<class T>
DualList<T>& DualList<T>::operator = (const DualList<T>& table)
{
this->DeepCopy(table);
return *this;
}
template<class T>
DualList<T>& DualList<T>::operator = (const Table<T>& table)
{
this->DeepCopy(table);
return *this;
}
template<class T>
void DualList<T>::Clear()
{
this->tail->next = NULL;
DListNode<T>*p = (DListNode<T>*)(this->head->next);
while(p != NULL)
{
DListNode<T> *pn = (DListNode<T>*)(p->next);
delete p;
p = pn;
}
this->curPos = this->tail = this->head->next = this->head;
((DListNode<T>*)this->head)->pre = this->head;
this->length = 0;
this->cur = -1;
}
template<class T>
const T* DualList<T>::GetPre(const T*p)const
{
return (p == NULL || p == ((const T*)(this->head->next))) ? NULL : (const T*)(((const DListNode<T>*)p)->pre);
}
template<class T>
const T& DualList<T>::GetAt(long index)const
{
ListNode<T>*p = this->curPos;
long i = this->cur;
for (; i < index; i++, p = p->next)
{
;
}
for (; i > index; i--, p = ((DListNode<T>*)p)->pre)
{
;
}
return p->data;
}
template<class T>
void DualList<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;
((DListNode<T>*)pre)->pre = p;
pre = p;
}
p = this->head->next;
this->head->next = this->tail;
((DListNode<T>*)this->tail)->pre = this->head;
this->tail = p;
}
template<class T>
void DualList<T>::Arrange(bool bIncrease)
{
if (this->GetLength() < 2)
{
return;
}
if (bIncrease)
{
this->MoveToFirst();
this->MoveToNext();
while(!this->IsBegin())
{
T temp = this->GetCurData();
long i = this->GetCur();
ListNode<T>* pos = this->GetCurPos();
MoveToPre();
if (this->GetCurData() > temp)
{
while(!this->IsBegin() && this->GetCurData() > temp)
{
MoveToPre();
}
InsertAfterCur(temp);
this->curPos = pos;
this->cur = i + 1;
DelCur();
}
else
{
this->MoveToNext();
}
this->MoveToNext();
}
}
else
{
this->MoveToFirst();
this->MoveToNext();
while(!this->IsBegin())
{
T temp = this->GetCurData();
long i = this->GetCur();
ListNode<T>*pos = this->GetCurPos();
MoveToPre();
if (this->GetCurData() < temp)
{
while(!this->IsBegin() && this->GetCurData() < temp)
{
MoveToPre();
}
InsertAfterCur(temp);
this->curPos = pos;
this->cur = i + 1;
DelCur();
}
else
{
this->MoveToNext();
}
this->MoveToNext();
}
}
}
template<class T>
void DualList<T>::Arrange(int (*cmp)(const T&,const T&))
{
if (this->GetLength() < 2)
{
return;
}
this->MoveToFirst();
this->MoveToNext();
while(!this->IsBegin())
{
T temp = this->GetCurData();
long i = this->GetCur();
ListNode<T>* pos = this->GetCurPos();
MoveToPre();
if (cmp(this->GetCurData(),temp) > 0)
{
while(!this->IsBegin() && cmp(this->GetCurData(),temp) > 0)
{
MoveToPre();
}
InsertAfterCur(temp);
this->curPos = pos;
this->cur = i + 1;
DelCur();
}
else
{
this->MoveToNext();
}
this->MoveToNext();
}
}
template<class T>
void DualList<T>::InsertAfterCur(const T& t)
{
DListNode<T>* p = new DListNode<T>;
p->data = t;
p->next = this->curPos->next;
this->curPos->next = p;
p->pre = this->curPos;
((DListNode<T>*)(p->next))->pre = p;
this->length++;
this->cur++;
if (this->curPos == this->tail)
{
this->tail = p;
}
this->curPos = p;
}
template<class T>
void DualList<T>::DelCur()
{
DListNode<T>* p = (DListNode<T>*)this->curPos;
MoveToPre();
this->curPos->next = p->next;
((DListNode<T>*)(p->next))->pre = this->curPos;
if (p == this->tail)
{
this->tail = this->curPos;
}
delete p;
this->length--;
}
template<class T>
DualList<T>::DualList(long initLength)
{
delete this->head;
this->head = this->tail = new DListNode<T>;
this->head->next = this->head;
((DListNode<T>*)this->head)->pre = this->head;
this->curPos = this->head;
this->Realloc(initLength);
}
template<class T>
DualList<T>::DualList(const Table<T>&table)
{
delete this->head;
this->head = this->tail = new DListNode<T>;
this->head->next = this->head;
((DListNode<T>*)this->head)->pre = this->head;
this->curPos = this->head;
this->DeepCopy(table);
}
template<class T>
DualList<T>::DualList(const DualList<T>&table)
{
delete this->head;
this->head = this->tail = new DListNode<T>;
this->head->next = this->head;
((DListNode<T>*)this->head)->pre = this->head;
this->curPos = this->head;
this->DeepCopy(table);
}
template<class T>
DualList<T>::~DualList()
{
if (this->head == NULL)
{
return;
}
Clear();
DListNode<T>* p = (DListNode<T>*)this->head;
delete p;
this->head = NULL;
}
template<class T>
void DualList<T>::MoveToPre()
{
this->curPos = ((DListNode<T>*)this->curPos)->pre;
this->cur--;
if (this->curPos == this->tail)
{
this->cur = this->length - 1;
}
}
template<class T>
void DualList<T>::MoveTo(long index)
{
if (this->IsValidIndex(index))
{
if (index == 0)
{
this->curPos = this->head->next;
this->cur = 0;
}
else if (index == this->GetLastIndex())
{
this->curPos = this->tail;
this->cur = index;
}
else if (index >= this->cur)
{
while(this->GetCur() != index)
{
this->MoveToNext();
}
}
else
{
while(this->GetCur() != index)
{
MoveToPre();
}
}
}
else
{
this->cur = -1;
this->curPos = this->head;
}
}
template<class T>
long DualList<T>::Conbine(List<T>&list,long from)
{
if (list.IsValidIndex(from))
{
ListNode<T>*first, *last;
list.MoveTo(from);
first = list.GetCurPos();
list.MoveToLast();
last = list.GetCurPos();
this->length += list.GetLength() - from;
list.DetachAfter(from - 1);
this->tail->next = first;
((DListNode<T>*)first)->pre = this->tail;
this->tail = last;
this->tail->next = this->head;
((DListNode<T>*)this->head)->pre = this->tail;
}
return this->length;
}
template<class T>
void DualList<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 = this->GetCurPos();
MoveTo(iNewZero);
//形成环路
this->tail->next = this->head->next;
((DListNode<T>*)this->head->next)->pre = this->tail;
//更新head
this->head->next = this->curPos;
((DListNode<T>*)this->curPos)->pre = this->head;
this->cur = 0;
//更新tail
this->tail = newTail;
this->tail->next = this->head;
((DListNode<T>*)this->head)->pre = this->tail;
}
}
template<class T>
void DualList<T>::DetachAfterCur()
{
this->curPos->next = this->head;
((DListNode<T>*)this->head)->pre = this->curPos;
this->tail = this->curPos;
this->length = this->cur + 1;
}
#endif