//-------------------------------------------------------------------------------------------------------+ // 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 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& operator << (DList&listother); //复制 DList& copyFrom(const DList& 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* m_pCurrent; protected: int m_nDelFlag; Node* head; Node* tail; virtual int Compare(const R *, const R *) const; private: DList & operator = (const DList &src); DList(const DList &src); }; template DList::DList(const DList &src) { m_nDelFlag = src.m_nDelFlag; for (int i = 0;i < src.Length();i++) { Append(new R( src[i] ) ); } } template inline DList::DList(int nFlag) { head = tail = m_pCurrent = NULL; m_nDelFlag = nFlag; m_nCurIndex = 0; m_nLen = 0; } template DList::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 DList::~DList() { Node *p = head, *p1 = NULL; while(p) { p1 = p->next; if (m_nDelFlag) { if (p->data != NULL) { delete p->data; } } delete p; p = p1; } } template inline void DList::Append(R * node) { m_pCurrent = NULL; m_nCurIndex = m_nLen; Insert(node); } template inline void DList::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 inline int DList::Remove(int n) { (*this)[n]; return Remove(); } template inline int DList::CurPosition() const { return m_nCurIndex inline int DList::Length() const { return m_nLen; } template inline void DList::SetDelFlag(int nFlag) { m_nDelFlag = nFlag; } template inline int DList::GetDelFlag() const { return m_nDelFlag; } template inline int DList::operator !() const { if (head) { return 0; } return 1; } template inline const R & DList::operator [](int n) const { DList *pThis = (DList *)this; const R * pData = (*pThis)[n]; return *pData; } template inline void DList::MoveToHead() { m_pCurrent = head; m_nCurIndex = 0; } // 移到当前指针到第 n 个节点, 并返回它 // 假如 n<0, exit; ||则移到倒数第 n个节点 template inline R * DList::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 inline const R & DList::GetAt(int n) const { DList *pThis = (DList *)this; const R * pData = (*pThis).GetAt(n); return *pData; } // 移到当前指针到第 n 个节点, 并返回它 // 假如 n<0, exit; ||则移到倒数第 n个节点 template inline R * DList::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 inline R * DList::CurData() const { return m_pCurrent ? m_pCurrent->data : NULL; } template inline void DList::SetCurData(R* p) { if (m_pCurrent != NULL) { m_pCurrent->data = p; } } template inline void DList::MoveEnd() { m_nCurIndex = -1; m_pCurrent = NULL; } template inline R* DList::Head() const { if (head) { return head->data; } return NULL; } template inline R* DList::Tail() const { if (tail) { return tail->data; } return NULL; } template inline void DList::FindAndDel(const void *p, int (*cmp)(const R *, const void *)) { while(FindNode(p,cmp) != NULL) { Remove(); } } //并入链表,list被直接连接到this链表的末尾,成为this链表的一部分 //最后this链表的游标值不变,而list变为Reset状态 template DList& DList::operator << (DList &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 DList& DList::copyFrom(const DList& 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 inline DList & DList::operator = (const DList &src) { return copyFrom(src); } // 重新初始化 template void DList::Reset() { Node *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 int DList::Exist(const R * node) const { for (Node *p = head; p != NULL; p = p->next) { if (Compare(p->data, node) == 0) { return 1; } } return 0; } template int DList::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 inline int DList::Compare(const R * node1, const R *node2) const { if (node1 == node2) { return 0; } return 1; } // 删除当前节点 template int DList::Remove() { if (!m_pCurrent) { return 0; } Node *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 void DList::Insert( R *dat) { assert(dat != NULL); if (head == NULL) { head = tail = new Node (NULL, NULL, dat); assert(head != NULL); m_pCurrent = NULL; //缺省插入尾部 } else if (m_pCurrent == NULL) { //加到尾部 Node *tmp =new Node (tail, NULL, dat); assert(tmp != NULL); tail->next = tmp; tail = tmp; } else if (m_pCurrent->previous) { //插入中间 Node *p = m_pCurrent->previous; p->next = m_pCurrent->previous = new Node (p,m_pCurrent,dat); assert(p->next != NULL); } else if (m_pCurrent == head) { // 加到表头前 curren == head head = new Node (NULL, m_pCurrent, dat); assert(head != NULL); m_pCurrent->previous = head; } m_nLen++; m_nCurIndex++; } template void DList::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 *n1 = m_pCurrent; R *s2 = (*this)[j + 1]; Node *n2 = m_pCurrent; nsr = cmp(s1, s2); if (nsr > 0) { R *tmp = s1; n1->data = s2; n2->data = tmp; } } } } // 可以用关键字查找链表中的某一项, 因此用 void * template R * DList::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 void DList::Swap(int n1,int n2) { if ((n1 >= 0 && n1 < m_nLen) && ( n2 >= 0 && n2 < m_nLen)) { R* swap1=(*this)[n1]; Node *node1 = m_pCurrent; R* swap2 = (*this)[n2]; Node *node2 = m_pCurrent; R *temp = swap1; node1->data = swap2; node2->data = temp; } else { assert(NULL); } } template void DList::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