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

691 lines
11 KiB
C++

//-------------------------------------------------------------------------------------------------------+
// Copyright (C), 1998-2007, SH Software Co. Ltd.
// = FileName : DList 模板类
// = Version : ver2.0
// = Author : zjq
// = CreateDate : 2002-09-09
// = Description: DList 声明 双向链表
// = Maintainers:
//
//-------------------------------------------------------------------------------------------------------+
#ifndef _DLIST_H_
#define _DLIST_H_
#ifndef _NODE_H_
#include "Node.h"
#endif
template <class R>
class DList
{
public:
DList(int dFlag = 1);
// 用数组初始化链表, 不能用于字符串数组!!
DList(R * addr, int nCount);
~DList();
int operator !() const;
// 移到当前指针到第 n 个节点, 并返回它所指的值
R * operator [](int n);
const R & operator [](int n) const;
void MoveToHead();
const R & GetAt(int n) const;
R * GetAt(int n);
//并入
DList<R>& operator << (DList<R>&listother);
//复制
DList<R>& copyFrom(const DList<R>& listother);
void Insert(R * node);
void Append(R * node);
void Replace(R * node, int n = -1);
void Reset();
int Remove();
int Remove(int n);
// 求当前指针的位置(-1: current 为 NULL)
int CurPosition() const;
int Length() const;
int GetDelFlag() const;
void SetDelFlag(int nFlag);
R * CurData() const;
void SetCurData(R* p);
int Find(const R * node);
int Exist(const R * node) const;
// 把指针移到最后,准备下一个插入
void MoveEnd();
R* Head() const;
R* Tail() const;
R* FindNode(const void *, int (*cmp)(const R *, const void *));
void QuickSort(int (*cmp)(const R *, const R *));
void Swap(int n1,int n2);
void Reverse();
void FindAndDel(const void *p, int (*cmp)(const R *, const void *));
private:
int m_nLen, m_nCurIndex;
Node<R>* m_pCurrent;
protected:
int m_nDelFlag;
Node<R>* head;
Node<R>* tail;
virtual int Compare(const R *, const R *) const;
private:
DList<R> & operator = (const DList<R> &src);
DList(const DList<R> &src);
};
template <class R>
DList<R>::DList(const DList<R> &src)
{
m_nDelFlag = src.m_nDelFlag;
for (int i = 0;i < src.Length();i++)
{
Append(new R( src[i] ) );
}
}
template <class R>
inline DList<R>::DList(int nFlag)
{
head = tail = m_pCurrent = NULL;
m_nDelFlag = nFlag;
m_nCurIndex = 0;
m_nLen = 0;
}
template <class R>
DList<R>::DList( R *pBeg, int nCount) : head(NULL), tail(NULL), m_pCurrent(NULL), m_nDelFlag(1), m_nCurIndex(0), m_nLen(0)
{
R *p = pBeg;
for (int i = 0; i < nCount; i++)
{
Append(new R(*p));
p++;
}
}
template <class R>
DList<R>::~DList()
{
Node<R> *p = head, *p1 = NULL;
while(p)
{
p1 = p->next;
if (m_nDelFlag)
{
if (p->data != NULL)
{
delete p->data;
}
}
delete p;
p = p1;
}
}
template <class R>
inline void DList<R>::Append(R * node)
{
m_pCurrent = NULL;
m_nCurIndex = m_nLen;
Insert(node);
}
template <class R>
inline void DList<R>::Replace(R * node, int n)
{
if (n >= 0)
{
(*this)[n];
}
if (m_pCurrent)
{
if (m_nDelFlag)
{
if (m_pCurrent->data != NULL)
{
delete m_pCurrent->data;
}
}
m_pCurrent->data = node;
}
}
template <class R>
inline int DList<R>::Remove(int n)
{
(*this)[n];
return Remove();
}
template <class R>
inline int DList<R>::CurPosition() const
{
return m_nCurIndex<m_nLen ? m_nCurIndex : -1;
}
template <class R>
inline int DList<R>::Length() const
{
return m_nLen;
}
template <class R>
inline void DList<R>::SetDelFlag(int nFlag)
{
m_nDelFlag = nFlag;
}
template <class R>
inline int DList<R>::GetDelFlag() const
{
return m_nDelFlag;
}
template <class R>
inline int DList<R>::operator !() const
{
if (head)
{
return 0;
}
return 1;
}
template <class R>
inline const R & DList<R>::operator [](int n) const
{
DList<R> *pThis = (DList<R> *)this;
const R * pData = (*pThis)[n];
return *pData;
}
template <class R>
inline void DList<R>::MoveToHead()
{
m_pCurrent = head;
m_nCurIndex = 0;
}
// 移到当前指针到第 n 个节点, 并返回它
// 假如 n<0, exit; ||则移到倒数第 n个节点
template <class R>
inline R * DList<R>::operator [](int n)
{
int i = 0;
if (n >= 0 && n < m_nLen)
{
if (!m_pCurrent)
{
m_pCurrent=head;
m_nCurIndex=0;
}
int diff = n - m_nCurIndex;
if (diff >= 0)
{
if (m_nCurIndex == 0 && n == m_nLen - 1)
{
m_pCurrent=tail;
m_nCurIndex=m_nLen - 1;
}
else
{
for (i = 0; i < diff; i++)
{
assert(m_pCurrent != NULL);
m_pCurrent = m_pCurrent->next;
}
}
}
else
{
if (m_nCurIndex == m_nLen - 1 && n == 0)
{
m_pCurrent=head;
m_nCurIndex=0;
}
else
{
for (i = 0; i < -diff; i++)
{
assert(m_pCurrent != NULL);
m_pCurrent = m_pCurrent->previous;
}
}
}
}
else
{
assert(0);
}
m_nCurIndex = n;
if (m_pCurrent)
{
return m_pCurrent->data;
}
return NULL;
}
template <class R>
inline const R & DList<R>::GetAt(int n) const
{
DList<R> *pThis = (DList<R> *)this;
const R * pData = (*pThis).GetAt(n);
return *pData;
}
// 移到当前指针到第 n 个节点, 并返回它
// 假如 n<0, exit; ||则移到倒数第 n个节点
template <class R>
inline R * DList<R>::GetAt(int n)
{
int i = 0;
if (n >= 0 && n < m_nLen)
{
if (!m_pCurrent)
{
m_pCurrent=head;
m_nCurIndex=0;
}
int diff = n - m_nCurIndex;
if (diff >= 0)
{
for (i = 0; i < diff; i++)
{
assert(m_pCurrent != NULL);
m_pCurrent = m_pCurrent->next;
}
}
else
{
if (m_nCurIndex == m_nLen - 1 && n == 0)
{
m_pCurrent=head;
m_nCurIndex=0;
}
else
{
for (i = 0; i < -diff; i++)
{
assert(m_pCurrent != NULL);
m_pCurrent = m_pCurrent->previous;
}
}
}
}
else
{
assert(0);
}
m_nCurIndex = n;
if (m_pCurrent)
{
return m_pCurrent->data;
}
return NULL;
}
template <class R>
inline R * DList<R>::CurData() const
{
return m_pCurrent ? m_pCurrent->data : NULL;
}
template <class R>
inline void DList<R>::SetCurData(R* p)
{
if (m_pCurrent != NULL)
{
m_pCurrent->data = p;
}
}
template <class R>
inline void DList<R>::MoveEnd()
{
m_nCurIndex = -1;
m_pCurrent = NULL;
}
template <class R>
inline R* DList<R>::Head() const
{
if (head)
{
return head->data;
}
return NULL;
}
template <class R>
inline R* DList<R>::Tail() const
{
if (tail)
{
return tail->data;
}
return NULL;
}
template <class R>
inline void DList<R>::FindAndDel(const void *p, int (*cmp)(const R *, const void *))
{
while(FindNode(p,cmp) != NULL)
{
Remove();
}
}
//并入链表,list被直接连接到this链表的末尾,成为this链表的一部分
//最后this链表的游标值不变,而list变为Reset状态
template <class R>
DList<R>& DList<R>::operator << (DList<R> &listother)
{
if (listother.Length() == 0)
{
return *this;
}
if (Length() > 0)
{
tail->next = listother.head;
listother.head->previous = tail;
}
else
{
head = listother.head;
}
//new tail
tail = listother.tail;
//increase length
m_nLen += listother.Length();
//reset list
listother.head = listother.tail = listother.m_pCurrent = NULL;
listother.m_nLen = listother.m_nCurIndex = 0;
return *this;
}
template <class R>
DList<R>& DList<R>::copyFrom(const DList<R>& listother)
{
m_nDelFlag = listother.m_nDelFlag;
if (this != &listother)
{
Reset();
for (int i = 0;i < listother.Length();i++)
{
Append(new R( listother[i] ) );
}
}
return *this;
}
template <class R>
inline DList<R> & DList<R>::operator = (const DList<R> &src)
{
return copyFrom(src);
}
// 重新初始化
template <class R>
void DList<R>::Reset()
{
Node<R> *p = head, *p1 = NULL;
while(p)
{
p1 = p->next;
if (m_nDelFlag)
{
if (p->data != NULL)
{
delete p->data;
}
}
delete p;
p = p1;
}
head = tail = m_pCurrent = NULL;
m_nLen = 0; m_nCurIndex = 0;
}
template <class R>
int DList<R>::Exist(const R * node) const
{
for (Node<R> *p = head; p != NULL; p = p->next)
{
if (Compare(p->data, node) == 0)
{
return 1;
}
}
return 0;
}
template <class R>
int DList<R>::Find(const R * node)
{
for (m_nCurIndex = 0; m_nCurIndex < m_nLen; m_nCurIndex++)
{
if (Compare((*this)[m_nCurIndex], node) == 0)
{
return 1;
}
}
return 0;
}
template <class R>
inline int DList<R>::Compare(const R * node1, const R *node2) const
{
if (node1 == node2)
{
return 0;
}
return 1;
}
// 删除当前节点
template <class R>
int DList<R>::Remove()
{
if (!m_pCurrent)
{
return 0;
}
Node<R> *p, *n;
p = m_pCurrent->previous;
n = m_pCurrent->next;
if (m_pCurrent == head)
{ //删除头节点
if (m_nDelFlag)
{
if (m_pCurrent->data != NULL)
{
delete m_pCurrent->data;
}
}
delete m_pCurrent;
head = m_pCurrent = n;
if (!n)
{
tail = NULL;
}
if (n)
{
n->previous = NULL;
}
}
else if (p)
{ // 当前节点变为下一个节点
if (m_nDelFlag)
{
if (m_pCurrent->data != NULL)
{
delete m_pCurrent->data;
}
}
delete m_pCurrent;
p->next = n;
if (n)
{
n->previous = p;
}
else
{
tail = p; //删除尾节点
}
m_pCurrent = n;
}
else
{
assert(0);
}
m_nLen--;
return 1;
}
// 在当前节点之前增加
template <class R>
void DList<R>::Insert( R *dat)
{
assert(dat != NULL);
if (head == NULL)
{
head = tail = new Node<R> (NULL, NULL, dat);
assert(head != NULL);
m_pCurrent = NULL; //缺省插入尾部
}
else if (m_pCurrent == NULL)
{ //加到尾部
Node<R> *tmp =new Node<R> (tail, NULL, dat);
assert(tmp != NULL);
tail->next = tmp;
tail = tmp;
}
else if (m_pCurrent->previous)
{ //插入中间
Node<R> *p = m_pCurrent->previous;
p->next = m_pCurrent->previous = new Node<R> (p,m_pCurrent,dat);
assert(p->next != NULL);
}
else if (m_pCurrent == head)
{ // 加到表头前 curren == head
head = new Node<R> (NULL, m_pCurrent, dat);
assert(head != NULL);
m_pCurrent->previous = head;
}
m_nLen++;
m_nCurIndex++;
}
template <class R>
void DList<R>::QuickSort(int (*cmp)(const R *, const R *))
{
int len = Length(), nsr = -1;
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
R *s1 = (*this)[j];
Node<R> *n1 = m_pCurrent;
R *s2 = (*this)[j + 1];
Node<R> *n2 = m_pCurrent;
nsr = cmp(s1, s2);
if (nsr > 0)
{
R *tmp = s1;
n1->data = s2;
n2->data = tmp;
}
}
}
}
// 可以用关键字查找链表中的某一项, 因此用 void *
template <class R>
R * DList<R>::FindNode(const void *target, int (*cmp)(const R *, const void *))
{
int len = Length(), nsr = -1;
for (int i = 0; i < len; i++)
{
R *s1 = (*this)[i];
nsr = cmp(s1, target);
if (!nsr)
{
return s1;
}
}
return NULL;
}
template <class R>
void DList<R>::Swap(int n1,int n2)
{
if ((n1 >= 0 && n1 < m_nLen) && ( n2 >= 0 && n2 < m_nLen))
{
R* swap1=(*this)[n1];
Node<R> *node1 = m_pCurrent;
R* swap2 = (*this)[n2];
Node<R> *node2 = m_pCurrent;
R *temp = swap1;
node1->data = swap2;
node2->data = temp;
}
else
{
assert(NULL);
}
}
template <class R>
void DList<R>::Reverse()
{
CPtrArray arPtrs;
int i = 0;
for (i = 0; i < m_nLen; i++)
{
arPtrs.Add((*this)[i]);
}
for (i = 0; i < m_nLen; i++)
{
(*this)[i];
m_pCurrent->data = (R*)arPtrs.GetAt(m_nLen - i - 1);
}
}
#endif