#pragma once #include #include #include #define DELETE_PTR(ptr)\ if (ptr)\ {\ delete ptr;\ ptr = NULL;\ } template class TDPtrList { typedef std::vector KVec; typedef int(*cmpFunc)(const K *, const K *); // 比较函数 typedef int(*cmpByVoidPtr)(const K *, const void *); // 比较函数 // 由于DList内的QuickSort()函数的排序结果与std::sort()的相反. // 故用此functor在 QuickSort()内部,将 cmpFunc的结果取反,以达到与DList结果相同的目的! struct TSort { cmpFunc func; TSort (cmpFunc f): func(f){} bool operator () (const K *p1, const K * p2) { bool brel = func(p1, p2) > 0 ? true : false; return !brel; } }; protected: bool m_nDelFlag; // true - 自动释放 K *head; // 头元素,为兼容DList K *tail; // 尾元素,为兼容DList private: KVec m_data; size_t m_pos; // 当前位置,为兼容DList public: TDPtrList(int dFlag = 1); // 用数组初始化链表, 不能用于字符串数组!! // 建议 K 有copy constructor TDPtrList(K * addr, size_t nCount); ~TDPtrList(); int operator !() const; // 移到当前指针到第 n 个节点, 并返回它所指的值 K * operator [](int n); const K & operator [](int n) const; void MoveToHead(); const K & GetAt(int n) const; K * GetAt(int n); //并入 //并入链表,listother被直接连接到this的末尾 //最后this链表的游标值不变, listother失去对其内数据的维护权. TDPtrList& operator << (TDPtrList &listother); //复制 //建议 K 有copy constructor TDPtrList& copyFrom(const TDPtrList &listother); void Insert(K * node); void Append(K * node); void Replace(K * 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); K * CurData() const; void SetCurData(K* p); // 如cmp为空,则直接比较指针地址. // 如cmp不为空,则比较指针所指内容. int Find(const K * node); int Exist(const K * node) const; // 把指针移到最后,准备下一个插入 void MoveEnd(); K* Head() const; K* Tail() const; K* FindNode(const void *, cmpByVoidPtr cmp); void QuickSort(cmpFunc cmp); void Swap(int n1,int n2); void Reverse(); void FindAndDel(const void *p, cmpByVoidPtr cmp); KVec& GetData(); const KVec& GetData() const; protected: virtual int Compare(const K *, const K *) const; private: TDPtrList & operator = (const TDPtrList &src); TDPtrList(const TDPtrList &src); bool judge_idx(size_t idx) const; void set_head_tail(); }; ////////////////////////////////////////////////////////////////////////// template void TDPtrList::set_head_tail() { if (m_data.empty()) head = tail = NULL; else { head = m_data.front(); tail = m_data.back(); } } template std::vector& TDPtrList::GetData() { return m_data; } template const std::vector& TDPtrList::GetData() const { return m_data;} template bool TDPtrList::judge_idx( size_t idx ) const { if (idx >= 0 && idx < m_data.size()) return true; return false; } template TDPtrList::TDPtrList( int dFlag /*= 1*/ ) : m_nDelFlag(dFlag != 0 ? true : false), m_data(0), head(NULL), tail(NULL), m_pos(0){set_head_tail();} template TDPtrList::TDPtrList( K * addr, size_t nCount) : m_nDelFlag(true), m_pos(0), head(NULL), tail(NULL), m_data(0) { m_data.resize(nCount); for (size_t i = 0; i < nCount; ++i, ++m_pos) m_data[i] = new K(addr[i]); set_head_tail(); } template TDPtrList::~TDPtrList() { if (!m_nDelFlag) return; for (size_t i = 0; i < m_data.size(); ++i) { K *p = m_data[i]; DELETE_PTR(p); } } template const K & TDPtrList::operator[]( int n ) const { return GetAt(n); } template K * TDPtrList::operator[]( int n ) { return GetAt(n); } template K * TDPtrList::GetAt( int n ) { m_pos = n; return m_data[n]; } template const K & TDPtrList::GetAt( int n ) const { TDPtrList *pThis = (TDPtrList *)this; const K *p = pThis->GetAt(n); return *p; } template TDPtrList& TDPtrList::copyFrom( const TDPtrList& listother ) { if (this == &listother) return *this; Reset(); m_nDelFlag = listother.GetDelFlag() != 0 ? true : false; m_data.resize(listother.Length()); for (size_t i = 0; i < (size_t)listother.Length(); ++i,++m_pos) m_data[i] = new K (listother[(int)i]); set_head_tail(); return *this; } template TDPtrList& TDPtrList::operator << ( TDPtrList &listother ) { KVec &odata = listother.GetData(); m_data.insert(m_data.end(), odata.begin(), odata.end()); listother.head = listother.tail = NULL; listother.m_pos = 0; listother.GetData().clear(); set_head_tail(); return *this; } template void TDPtrList::Insert( K * node ) { if (!judge_idx(m_pos)) { Append(node); return; } typename KVec::iterator it = m_data.begin(); std::advance(it , m_pos); m_data.insert(it, node); set_head_tail(); ++m_pos; } template void TDPtrList::Append( K * node ) { m_data.push_back(node); // dlist在进行尾插入后,其当前索引会指到结尾的下一个内存处,而不是最后一个元素. // 对此我表示理解无能... m_pos = m_data.size(); set_head_tail(); } template void TDPtrList::Replace( K * node, int n /*= -1*/ ) { if (!judge_idx((size_t)n)) return; if (m_nDelFlag) DELETE_PTR(m_data[n]); m_data[n] = node; m_pos = n; set_head_tail(); } template void TDPtrList::Reset() { if (m_nDelFlag) { for (size_t i = 0; i < m_data.size(); ++i) DELETE_PTR(m_data[i]); } m_data.clear(); head = tail = NULL; m_pos = 0; } template int TDPtrList::Exist( const K * node) const { return const_cast*>(this)->Find(node); } template int TDPtrList::Find( const K * node) { TDPtrList *p = (TDPtrList*) this; for ( m_pos = 0; m_pos < m_data.size(); ++m_pos) { if (!Compare(m_data[m_pos], node)) return 1; } return 0; } template void TDPtrList::SetCurData( K* p ) // dlist 在这里只是简单替换,并没有考虑内存释放问题 { if (!judge_idx(m_pos)) return; if (m_nDelFlag) DELETE_PTR(m_data[m_pos]); m_data[m_pos] = p; set_head_tail(); } template K * TDPtrList::CurData() const { if (!judge_idx(m_pos)) return NULL; return m_data[m_pos]; } template void TDPtrList::SetDelFlag( int nFlag ) { m_nDelFlag = nFlag != 0 ? true : false; } template int TDPtrList::GetDelFlag() const { return m_nDelFlag; } template int TDPtrList::Length() const { return (int)m_data.size(); } template int TDPtrList::CurPosition() const { return m_pos < m_data.size() ? (int)m_pos : -1; } template int TDPtrList::Remove( int n ) { if (!judge_idx((size_t)n)) return 0; m_pos = n; return Remove(); } template int TDPtrList::Remove() { if (!judge_idx(m_pos)) return 0; if (m_nDelFlag) DELETE_PTR(m_data[m_pos]); typename KVec::iterator it = m_data.begin(); std::advance(it, m_pos); m_data.erase(it); set_head_tail(); return 1; } // 注意dlist用的是指针比较,所以...这里也是如此 template int TDPtrList::Compare( const K *p1, const K *p2 ) const { if (p1 == p2) return 0; return 1; } template TDPtrList::TDPtrList( const TDPtrList &src ) : m_nDelFlag(true), m_pos(0), head(NULL), tail(NULL), m_data(0){ copyFrom(src); } template TDPtrList & TDPtrList::operator=( const TDPtrList &src ) { return copyFrom(src); } template void TDPtrList::FindAndDel( const void *p, cmpByVoidPtr cmp ) { while (FindNode(p, cmp)) Remove(); } template void TDPtrList::Reverse() { std::reverse(m_data.begin(), m_data.end()); set_head_tail(); } template void TDPtrList::Swap( int n1, int n2 ) { if (!judge_idx((size_t)n1) || !judge_idx((size_t)n2)) return; K *tmp = m_data[n1]; m_data[n1] = m_data[n2]; m_data[n2] = tmp; m_pos = n2; set_head_tail(); } template void TDPtrList::QuickSort( cmpFunc cmp ) { std::sort(m_data.begin(), m_data.end(), TSort(cmp)); set_head_tail(); } template K* TDPtrList::FindNode( const void *p, cmpByVoidPtr cmp ) { for (size_t i = 0; i < m_data.size(); ++i) { m_pos = i; K *result = m_data[i]; if (!cmp(result, p)) return result; } return NULL; } template K* TDPtrList::Tail() const {const_cast*>(this)->set_head_tail(); return tail; } template K* TDPtrList::Head() const {const_cast*>(this)->set_head_tail(); return head; } template void TDPtrList::MoveEnd() { m_pos = -1; } template void TDPtrList::MoveToHead() { m_pos = 0; } template int TDPtrList::operator!() const { if (head) { return 0; } return 1; }