#ifndef _LIST_H_VANEY_7DDEC326_04ED_46b2_21A0_051D70E560F7 #define _LIST_H_VANEY_7DDEC326_04ED_46b2_21A0_051D70E560F7 /****************************************************************** *名称 :list.h *版本 :1.00 *描述 :list模板类 *作者 :vaney.li@gmail.com *日期 :2010年11月2日 *版权 : *用例 : ******************************************************************/ #include "common.h" #include <iostream> using namespace std; _NAME_SPACE_BEGIN /** * 节点类,即模板链表中的节点,供模板链表使用 */ template<class TYPE> class TListItem { /** * 下一个节点 */ TListItem<TYPE>* _next; /** * 上一个节点 */ TListItem<TYPE>* _pre; /** * 节点的数据,即真正使用中的数据,主要是指针,如果你使用TListItem<CLine>即每个节点存放一个CLine指针,暂不支持TListItem<CLine*> */ TYPE* _data; public: /** * 构造函数 * @param data 节点内容,不需要拷贝,直接指针指向 */ TListItem(TYPE* data = 0) { _data = data; _next = _pre = 0; } /** * 析构函数,节点负责释放节点中的内容 */ virtual ~TListItem(void) { _pre = 0; _next = 0; if(_data) { //要求TYPE即为类,不能是类的指针。如class A; TListItem<A> 正确,TListItem<A*>错误!!! delete _data; } _data = 0; } public: /** * 重载运算符== * @param item 注意参数是引用不是值 */ int32 operator==(TListItem<TYPE> &item) { return (*_data) == *(item.GetData()); } /** * 重载运算符> * @param item 注意参数是引用不是值 */ int32 operator>(TListItem<TYPE> &item) { return (*_data) > *(item.GetData()); } /** * 重载运算符< * @param item 注意参数是引用不是值 */ int32 operator<(TListItem<TYPE> &item) { return (*_data) < *(item.GetData()); } /** * 重载运算符<= * @param item 注意参数是引用不是值 */ int32 operator<=(TListItem<TYPE> &item) { return (*_data) <= *(item.GetData()); } /** * 重载运算符>= * @param item 注意参数是引用不是值 */ int32 operator>=(TListItem<TYPE> &item) { return (*_data) >= *(item.GetData()); } /** * 重载运算符<< 即打印节点,如节点为:TListItem<TYPE> item,调用: cout<< item << endl 就会打印该节点 * @param os 标准输出流 * @param item 注意参数是引用不是值 */ friend inline ostream & operator << (ostream & os, TListItem<TYPE> &item) { //TYPE 类需要重载运算符<< cout << item._data; return os; } public: TYPE* GetData(void) const { return _data; } TListItem* GetNext(void) const { return _next; } TListItem* GetPre(void) const { return _pre; } TYPE* SetData(const TYPE* data) { if(_data && data != _data) { delete _data; } _data = data; } /** * 设置节点的下一节点指针 * @param next 节点指针 */ void SetNext(TListItem<TYPE>* next) { _next = next; } /** * 设置节点的下一节点指针 * @param next 节点指针 */ void SetPre(TListItem<TYPE>* pre) { _pre = pre; } }; /** * 有序插入,默认升序INSERT_ASCEND */ #define INSERT_DESCEND -2 #define INSERT_ASCEND -3 /** * 删除节点,删除制定节点,即比较节点的大小,TListItem<TYPE> node == TListItem<TYPE> node2 ? 删除:不删除 */ #define REMOVE_TAGET -4 /** * 删除节点,删除制定节点,删除链表中第index个节点 */ #define REMOVE_INDEX -5 /** * 节点链表模板,供模块类List使用。程序中只能使用List作为模板类。 */ template<class TYPE> class TList { /** * 节点游标,用于链表节点函数Begin(_cursor = 0), Next(_cursor ++),Before(_cursor --) */ int32 _cursor; protected: /** * 节点链表头 */ TListItem<TYPE>* _head; /** * 节点链表尾 */ TListItem<TYPE>* _tail; /** * 链表大小,即链表中节点个数 */ int32 _size; public: /** * 构造函数 */ TList(void) { _head = _tail = 0; _size = _cursor = 0; } /** * 析构函数,释放每个节点,每个节点负责释放节点中的内容 */ virtual ~TList(void) { TListItem<TYPE>* item = _head; //释放所有节点 while(_size-- && item) { TListItem<TYPE>* item_next = item->GetNext(); delete item; item = item_next; } } public: /** * 重载运算符<< 即打印链表,如节点为:TList<TYPE> link,调用: cout<< link << endl 就会打印该链表 * @param os 标准输出流 * @param item 注意参数是引用不是值 */ friend inline ostream & operator << (ostream & os, TList<TYPE> &list) { int32 size = list.GetSize(); TListItem<TYPE>* item = list.GetHead(); while(item) { TListItem<TYPE>* item_next = item->GetNext(); cout << "node : " << list.GetSize() - size << " id = " << *(item->GetData()) << endl; item = item_next; size--; } return os; } protected: /** * 重置游标,暂不使用该函数 */ void Reset(void) { _cursor = 0; } /** * 获取第一个节点,游标设为1 */ TListItem<TYPE>* Begin(void) { _cursor = 1; return _head; } /** * 获取最后一个节点,游标设为_size */ TListItem<TYPE>* End(void) { _cursor = _size; return _tail; } /** * 获取下一个节点,游标++ */ TListItem<TYPE>* Next(void) { if(_cursor == _size) { //游标到达尾部了 return 0; } if(!_cursor) { _cursor++; return _head; } if(!_cursor == _size - 1) { _cursor++; return _tail; } int32 index = _cursor; TListItem<TYPE>* node = _head; while(index--) { node = node->GetNext(); } _cursor++; return node; } /** * 获取上一个节点,游标++ */ TListItem<TYPE>* Before(void) { if(_cursor == 0) { //游标到达头了 return 0; } if(_cursor == 1) { _cursor--; return _head; } int32 index = _cursor; TListItem<TYPE>* node = _head; while(index--) { node = node->GetNext(); } _cursor--; return node->GetPre(); } /** * 有序插入, 默认升序INSERT_ASCEND 即排列方式如1,4,7,7,8,10,如果两个7即后插入的排在后面 * @param item 需要插入的节点信息 * @param index 需要操作的位置或者方式 */ void Insert(TListItem<TYPE>* item, int32 index = INSERT_ASCEND) { if(INSERT_DESCEND == index) { //降序插入 InsertDescend(item); return; } else if(INSERT_ASCEND == index) { //升序插入 InsertAscend(item); return; } //插入到index位置 InsertNormal(item, index); } /** * 删除节点 删除节点,默认REMOVE_TAGET删除制定节点,即比较节点的大小,TListItem<TYPE> node == TListItem<TYPE> node2 ? 删除:不删除 * @param item 需要删除的节点信息 * @param index 需要操作的位置或者方式 */ void Remove(TListItem<TYPE>* item, int32 index = REMOVE_TAGET ) { if(!item) { return; } TListItem<TYPE>* node = findnode(item,index); if(!node) { return; } if(_head == node) { _head->GetNext()->SetPre(0); _head = _head->GetNext(); } else if(_tail == node) { _tail->GetPre()->SetNext(0); _tail = _tail->GetPre(); } else { if(node->GetPre()) { node->GetPre()->SetNext(node->GetNext()); } if(node->GetNext()) { node->GetNext()->SetPre(node->GetPre()); } } delete node; node = 0; } /** * 删除第一个节点 */ void Pop_Front(void) { //删除第一个节点 if(!_head) { return; } TListItem<TYPE>* node = _head; _head->GetNext()->SetPre(0); _head = _head->GetNext(); delete node; node = 0; } /** * 删除最后一个节点 */ void Pop_End(void) { //删除最后一个节点 if(!_head) { return; } TListItem<TYPE>* node = _tail; _tail->GetPre()->SetNext(0); _tail = _tail->GetPre(); delete node; node = 0; } /** * 在链表头压入节点,即压入的节点为新的_head * @param item 需要压入的节点信息 */ void Push_Front(TListItem<TYPE>* item) { if(!item) { return; } if(!_head) { _head = item; _tail = item; item->SetNext(0); item->SetPre(0); _size++; return; } _head->SetPre(item); item->SetNext(_head); item->SetPre(0); _head = item; _size++; } /** * 在链表尾压入节点,即压入的节点为新的_tail * @param item 需要压入的节点信息 */ void Push_Back(TListItem<TYPE>* item) { if(!item) { return; } if(!_tail) { _head = item; _tail = item; item->SetNext(0); item->SetPre(0); _size++; return; } _tail->SetNext(item); item->SetPre(_tail); item->SetNext(0); _tail = item; _size++; } public: /** * 获取链表头 */ TListItem<TYPE>* GetHead(void) { return _head; } /** * 获取链表尾 */ TListItem<TYPE>* GetTail(void) { return _tail; } /** * 获取链表大小,即链表中有多少个节点 */ int32 GetSize(void) { return _size; } private: void InsertDescend(TListItem<TYPE>* item) { TListItem<TYPE>* node = findnode(item,INSERT_DESCEND); InsertAfterNode(item,node); } void InsertAscend(TListItem<TYPE>* item) { TListItem<TYPE>* node = findnode(item,INSERT_ASCEND); InsertAfterNode(item,node); } void InsertNormal(TListItem<TYPE>* item, int32 index) { TListItem<TYPE>* node = findnode(item,index); InsertAfterNode(item,node); } /** * 在链表中找到节点,按照不同的方式 * @param item 按item节点的要求找到相应的节点,如找到有相同data的节点 * @param index 寻找方式 */ TListItem<TYPE>* findnode(TListItem<TYPE>* item, int32 index) { TListItem<TYPE>* node = _head; switch(index) { //降序插入寻找方式,与item 值最近的节点。 链表是:9 8 5 2 如果item的内容是6,则返回8节点,6将插入到8后面 case INSERT_DESCEND: { if(!item) { return 0; } TListItem<TYPE>* node_find = 0; while(node) { if((*node)>=(*item)) { node_find = node; } node = node->GetNext(); } return node_find; } break; //升序插入寻找方式,与item 值最近的节点。 链表是:2 5 8 9 如果item的内容是6,则返回5节点,6将插入到5后面 case INSERT_ASCEND: { if(!item) { return 0; } TListItem<TYPE>* node_find = 0; while(node) { if((*node)<=(*item)) { node_find = node; } node = node->GetNext(); } return node_find; } break; //目标删除寻找方式,与item 值相等的节点。 链表是:2 5 8 9 如果item的内容是8,则返回8节点 case REMOVE_TAGET: { if(!item) { return 0; } TListItem<TYPE>* node_find = 0; while(node) { //并不是指针相等 if((*node)==(*item)) { node_find = node; return node_find; } node = node->GetNext(); } return node_find; } break; //索引删除寻找方式,索引为index 的节点。 链表是:2 5 8 9 如果index值是3,则返回8节点 case REMOVE_INDEX: { if(!item) { return 0; } while(node && index--) { node = node->GetNext(); } return node; } break; //返回尾节点 default: { while(index-- && node) { node = node->GetNext(); } } break; } return 0; } /** * 插入节点 将节点ITEM插入到节点NODE后面 * @param item 将要插入的节点 * @param node 将节点ITEM插入到节点NODE后面 */ void InsertAfterNode(TListItem<TYPE>* item,TListItem<TYPE>* node) { if(!_tail) { item->SetPre(0); item->SetNext(0); _head = item; _tail = item; _size ++; return; } if(node == _tail) { _tail->SetNext(item); item->SetPre(_tail); item->SetNext(0); _tail = item; _size ++; return; } if(node == _head) { item->SetNext(_head->GetNext()); item->SetPre(_head); _head->SetNext(item); _size ++; return; } if(!node) { item->SetNext(_head); item->SetPre(0); _head = item; _size ++; return; } item->SetNext(node->GetNext()); node->GetNext()->SetPre(item); node->SetNext(item); item->SetPre(node); _size ++; } }; /** * 模块类List。程序中只能使用List作为模板类。 */ template<class TYPE> class List : public TList<TYPE> { public: List(void) { } virtual ~List(void) { } public: /** * 重置游标,调用父类 */ void reset(void) { TList<TYPE>::Reset()->GetData(); } /** * 返回最后一个节点的值,注意父类TList<TYPE>中的End()只是返回最后一个节点 */ TYPE* end(void) { TListItem<TYPE>* item = TList<TYPE>::End(); if(!item) { return 0; } item->GetData(); } /** * 返回第一个节点的值 */ TYPE* begin(void) { TListItem<TYPE>* item = TList<TYPE>::Begin(); if(!item) { return 0; } return item->GetData(); } /** * 返回第下一个节点的值 */ TYPE* next(void) { TListItem<TYPE>* item = TList<TYPE>::Next(); if(!item) { return 0; } return item->GetData(); } /** * 返回第上一个节点的值 */ TYPE* before(void) { return TList<TYPE>::Before()->GetData(); } /** * 有序插人节点, 默认升序INSERT_ASCEND 即排列方式如1,4,7,7,8,10,如果两个7即后插入的排在后面 * @param data 需要插入的值,父类会根据该值创建新的节点,然后插入 * @param index 需要操作的位置或者方式 */ void insert(TYPE* data, int32 index = INSERT_ASCEND) { if(!data) { return; } TListItem<TYPE>* item = new TListItem<TYPE>(data); TList<TYPE>::Insert(item,index); } /** * 删除节点 删除节点,默认REMOVE_TAGET删除制定节点,即比较节点的大小,TListItem<TYPE> node == TListItem<TYPE> node2 ? 删除:不删除 * @param data 需要删除的节点信息,父类会根据该值寻找到链表中的节点,然后删除 * @param index 需要操作的位置或者方式 */ void remove(TYPE* data, int32 index = REMOVE_TAGET) { if(!data) { return; } if(index == REMOVE_TAGET) { TListItem<TYPE>* item = 0; TListItem<TYPE>* finded = TList<TYPE>::Begin(); while(finded) { if(finded->GetData() == data) { item = finded; break; } finded = TList<TYPE>::Next(); } //未找到节点 if(!item) { return; } if(item == _head) { if(_head->GetNext()) { _head->GetNext()->SetPre(0); } _head = _head->GetNext(); _size--; delete item; return; } if(item == _tail) { if(_tail->GetPre()) { _tail->GetPre()->SetNext(0); } _tail = _tail->GetPre(); _size--; delete item; return; } if(item->GetPre()) { item->GetPre()->SetNext(item->GetNext()); } if(item->GetNext()) { item->GetNext()->SetPre(item->GetPre()); } _size--; delete item; } else { TListItem<TYPE>* item = new TListItem<TYPE>(); TList<TYPE>::Remove(item,index); delete item; } } /** * 删除第一个节点 */ void pop_front(void) { //删除第一个节点 TList<TYPE>::Pop_Front(); } /** * 删除最后一个节点 */ void pop_end(void) { //删除第二个节点 TList<TYPE>::Pop_End(); } /** * 在链表头压入节点,即压入的节点为新的_head * @param data 父类会根据该值创建新的节点 */ void push_front(TYPE* data) { if(!data) { return; } TListItem<TYPE>* item = new TListItem<TYPE>(data); TList<TYPE>::Push_Front(item); } /** * 在链表尾压入节点,即压入的节点为新的_tail * @param data 父类会根据该值创建新的节点 */ void push_back(TYPE* data) { if(!data) { return; } TListItem<TYPE>* item = new TListItem<TYPE>(data); TList<TYPE>::Push_Back(item); } /** * 返回头结点值 */ TYPE* head(void) { return TList<TYPE>::GetHead()->GetData(); } /** * 返回尾结点值 */ TYPE* tail(void) { return TList<TYPE>::GetTail->GetData(); } /** * 返回尾链表大小,即有多少个节点 */ int32 size(void) { return TList<TYPE>::GetSize(); } }; _NAME_SPACE_END #endif