在实现时没有引入两个辅助节点,所以实现时需要考虑特殊情况,比如头和尾插入删除操作时,需要改变指向头和尾的指针。在做迭代器的时候还有麻烦,遍历链表时需要借助量表的长度,不然不能标识结束,我想到的办法是在迭代器中做一些记录工作,比如当前的下标和整个链表的长度。有解决办法的希望指教。
#ifndef LINKLIST_H#define LINKLIST_H#include "list.hpp"templatestruct node { T d; node *pre, *next; node(const T& _d, node *_pre = NULL, node *_next = NULL): d(_d), pre(_pre), next(_next) { }};template class LinkList : public List {public: /** * @brief The Iterator class 双循环链表设计时没有头和尾节点,所以在设计迭代器时不方便,比如遍历链表必须借助链表的长度 */ class Iterator { friend std::ostream& operator << (std::ostream &os, const Iterator &obj) { os << obj.p->d; return os; } public: Iterator(node *_p):p(_p){} ~Iterator(){} Iterator(const Iterator& obj):p(obj.p){} Iterator& operator = (const Iterator& obj) { p = obj.p; return *this; } Iterator& operator ++() { p = p->next; return *this; } Iterator operator ++(int) { Iterator t(p); p = p->next; return t; } Iterator& operator -- (){ p = p->pre; return *this; } Iterator operator -- (int) { Iterator t(p); p = p->pre; return t; } T operator * () { return p->d; } T* operator -> () { return &p->d; } bool operator == (const Iterator &ite) { return p == ite.p; } bool operator != (const Iterator &ite) { return p != ite.p; } private: node *p; }; LinkList():head(NULL),tail(NULL),size(0) {} ~LinkList(); void clear(); int length() const; /** * @brief insert 插入到链表的指定位置 插入i的下个位置 * @param i 下标 从0开始 * @param t */ void insert(int i, const T &t); int search(const T &t) const; T visit(int i) const; void traverse(std::ostream &os = std::cout) const; void remove(int i); void add(const T& o); void push_front(const T& o); void push_tail(const T& o); T pop_front(); T pop_tail(); Iterator begin() const { return Iterator(head); }private: node *head, *tail; int size; node * local(int i) const;};template LinkList ::~LinkList(){ clear();}template /** * @brief LinkList ::add 在双循环链表的tail添加节点 * @param o */void LinkList ::add(const T &o){ node *p = NULL; if (size == 0) { p = new node (o); head = tail = p; head->pre = tail; tail->next = head; } else { p = new node (o,tail,head); head->pre = p; tail->next = p; tail = p; } ++size;}template node *LinkList ::local(int i) const{ if (i < 0 ||i > size - 1) throw BadValue(); node *p = head; for (int j = 0;j < i;++j) { p = p->next; } return p;}template /** * @brief LinkList ::clear 只有一个节点 */void LinkList ::clear(){ node *p = head; while(size--) { head = head->next; delete p; p = head; } head = tail = NULL; size = 0;}template /** * @brief LinkList ::insert 插在i的后面 * @param i * @param t */void LinkList ::insert(int i, const T &t){ if ((size == 0 && i == 0) || size-1 == i) {//过滤掉空链表插入和尾部插入 add(t); } else { node *p = local(i);//i节点 node *n = p->next;//下个节点 node *d = new node (t,p,n); p->next = d; n->pre = d; ++size; }}template int LinkList ::length() const{ return size;}template int LinkList ::search(const T &t) const{ int re = -1; node *p = head; for (int i = 0;i < size;++i) { if (p->d == t) { re = i; break; } p = p->next; } return re;}template T LinkList ::visit(int i) const{ return local(i)->d;}template void LinkList ::remove(int i){ node *p = local(i); p->pre->next = p->next; p->next->pre = p->pre; --size; if (i == 0) { head = p->next; tail->next = head; } if (i == size-1) { tail = p->pre; head->pre = tail; } delete p;}template void LinkList ::traverse(std::ostream &os) const{ node *p = head; for (int i = 0;i < size;++i) { os << p->d << " "; p = p->next; }}template /** * @brief LinkList ::push_front 插入头部 * @param o */void LinkList ::push_front(const T &o){ node *p = new node (o,tail,head); p->next =head; p->pre = tail; head = p; ++size;}template void LinkList ::push_tail(const T &o){ add(o);}template T LinkList ::pop_front(){ T t = local(0)->d; remove(0); return t;}template T LinkList ::pop_tail(){ T t = local(size-1)->d; remove(size-1); return t;}#endif