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