双向链表:每个节点包含指向后继节点的指针和指向前驱节点的指针。
继承关系图:
实体图:
DualLinkList.h
/* * DualLinkList: 双向链表类模板 * 成员变量: * Node: 节点实体 * m_header: 头节点 * m_length 链表长度 * m_step 步进长度 * m_current 当前节点前一个节点 * 成员函数: * create() 申请一个新节点 * destroy() 删除一个新节点 * * DualLinList() 构造函数初始化成员变量 * insert() 参数判断,申请新节点,寻找节点,插入节点。分四步: * remove() 参数判断,寻找节点,删除节点。 分三步: * set() 参数判断,寻找节点,设置节点值 * get() 参数判断,寻找节点,获取节点值 * length() 获取链表长度 * clean() 释放所有节点空间 * find() 返回对应值得节点下标 * position() 返回下标pos节点的上一个的节点指针 * ~LinkList() 释放所有节点空间 * * bool move() 移动游标到指定位置 * bool end() 判断游标是否到最后 * T current() 回去当前游标节点值 * bool next() 移动步长的节点数 * bool pre() 移动步长的节点数 */ #ifndef DUALLINKLIST_H #define DUALLINKLIST_H #include"List.h" #include"Exception.h" namespace DSL { template <typename T> class DualLinkList : public List<T> { protected: struct Node : public TopClass { T value; Node* next; Node* pre; }; mutable struct : public TopClass { char reserve[sizeof(T)]; Node* next; Node* pre; }m_header; int m_length; int m_step; Node* m_current; virtual Node* create(const T& value) { Node* node = new Node(); node->value = value; if(node == NULL) { THROW_EXCEPTION(NotEnoughMemoryException,"error: no enough memory to create node!"); } return node; } virtual void destroy(Node* toDel) { delete toDel; } public: DualLinkList() { m_length = 0; m_step = 1; m_current = NULL; m_header.next = NULL; m_header.pre = NULL; } bool insert(const T& obj) { return insert(m_length,obj); } bool insert(int pos, const T& obj) { bool ret = ((0 <= pos) && (pos <= m_length)); if(ret) { Node* new_node = create(obj); Node* slider_node = reinterpret_cast<Node*>(&m_header); Node* head_node = reinterpret_cast<Node*>(&m_header); for(int i = 0; i < m_length; i++) { slider_node = slider_node->next; } Node* pre_node = slider_node; Node* next_node = slider_node->next; new_node->next = next_node; // pre节点指向new节点,new节点指向next节点 在任何情况下是安全操作 pre_node->next = new_node; if(pre_node == head_node) // 插入链表头部 { new_node->pre = NULL; } if(pre_node != head_node) //插入链表中间 { new_node->pre = pre_node; } if(next_node == NULL) //插入链表末尾 { ; } if(next_node != NULL) //插入链表中间 { next_node->pre = new_node; } m_length++; } return ret; } bool remove(int pos) { bool ret = ((pos >= 0) && (pos < m_length)); if(ret) { Node* slider_node = reinterpret_cast<Node*>(&m_header); for(int i = 0; i < pos; i++) { slider_node = slider_node->next; } Node* pre_node = slider_node; Node* toDel =slider_node->next; Node* next_node = toDel->next; Node* head_node = reinterpret_cast<Node*>(&m_header); pre_node->next = next_node; // pre节点指向next节点 在任何情况下是安全操作 if(next_node == NULL) // 删除尾节点 { ; } if(next_node != NULL) // 删除中间节点和头节点 { next_node->pre = toDel->pre; } m_length--; if(m_current == toDel) // 游标处理 { m_current = next_node; } destroy(toDel); } return ret; } bool set(int pos, const T& obj) { bool ret = ((0 <= pos) && (pos < m_length)); if(ret) { Node* slider_node = reinterpret_cast<Node*>(&m_header); for(int i = 0; i < pos; i++) { slider_node = slider_node->next; } slider_node->next->value = obj; } return ret; } T get(int pos) const { T ret; get(pos,ret); return ret; } bool get(int pos, T& obj) const { bool ret = ((0 <= pos) && (pos < m_length)); if(ret) { Node* slider_node = reinterpret_cast<Node*>(&m_header); for(int i = 0; i < pos; i++) { slider_node = slider_node->next; } obj = slider_node->next->value; } return ret; } int find(const T& obj) const { int ret = -1; Node* head_node = reinterpret_cast<Node*>(&m_header); Node* slider_node = head_node->next; for(int i = 0; i < m_length; i++) { if(slider_node->value == obj) { ret = i; break; } else { slider_node = slider_node->next; } } return ret; } int length() const { return m_length; } void clean() { while(m_length > 0) { remove(0); } } bool move(int pos) { bool ret = ((0 <= pos) && (pos < m_length)); if(ret) { Node* slider_node = reinterpret_cast<Node*>(&m_header); for(int i = 0; i < pos; i++) { slider_node = slider_node->next; } m_current = slider_node->next; } return ret; } bool end() { return (m_current == NULL); } T current() { if(m_current != NULL) { return m_current->value; } else { THROW_EXCEPTION(IdexOutOfBoundException,"error: operat a no exit node!"); } } bool next(int step = 1) { bool ret = (step > 0); if(ret) { for(int i = 0; (i < step) && (m_current != NULL); i++) { m_current = m_current->next; } } return ret; } bool pre(int step = 1) { bool ret = (step > 0); if(ret) { for(int i = 0; (i < step) && (m_current != NULL); i++) { m_current = m_current->pre; } } return ret; } ~DualLinkList() { clean(); } }; } #endif
扩展继承图: