在實現時沒有引入兩個輔助節點,因此實現時須要考慮特殊狀況,好比頭和尾插入刪除操做時,須要改變指向頭和尾的指針。在作迭代器的時候還有麻煩,遍歷鏈表時須要藉助量表的長度,否則不能標識結束,我想到的辦法是在迭代器中作一些記錄工做,好比當前的下標和整個鏈表的長度。有解決辦法的但願指教。node
#ifndef LINKLIST_H #define LINKLIST_H #include "list.hpp" template <typename T> struct node { T d; node *pre, *next; node(const T& _d, node *_pre = NULL, node *_next = NULL): d(_d), pre(_pre), next(_next) { } }; template <typename T> class LinkList : public List<T> { 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<T> *_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<T> *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<T> *head, *tail; int size; node<T>* local(int i) const; }; template <typename T> LinkList<T>::~LinkList() { clear(); } template <typename T> /** * @brief LinkList<T>::add 在雙循環鏈表的tail添加節點 * @param o */ void LinkList<T>::add(const T &o) { node<T> *p = NULL; if (size == 0) { p = new node<T>(o); head = tail = p; head->pre = tail; tail->next = head; } else { p = new node<T>(o,tail,head); head->pre = p; tail->next = p; tail = p; } ++size; } template <typename T> node<T> *LinkList<T>::local(int i) const { if (i < 0 ||i > size - 1) throw BadValue(); node<T> *p = head; for (int j = 0;j < i;++j) { p = p->next; } return p; } template <typename T> /** * @brief LinkList<T>::clear 只有一個節點 */ void LinkList<T>::clear() { node<T> *p = head; while(size--) { head = head->next; delete p; p = head; } head = tail = NULL; size = 0; } template <typename T> /** * @brief LinkList<T>::insert 插在i的後面 * @param i * @param t */ void LinkList<T>::insert(int i, const T &t) { if ((size == 0 && i == 0) || size-1 == i) {//過濾掉空鏈表插入和尾部插入 add(t); } else { node<T> *p = local(i);//i節點 node<T> *n = p->next;//下個節點 node<T> *d = new node<T>(t,p,n); p->next = d; n->pre = d; ++size; } } template <typename T> int LinkList<T>::length() const { return size; } template <typename T> int LinkList<T>::search(const T &t) const { int re = -1; node<T> *p = head; for (int i = 0;i < size;++i) { if (p->d == t) { re = i; break; } p = p->next; } return re; } template <typename T> T LinkList<T>::visit(int i) const { return local(i)->d; } template <typename T> void LinkList<T>::remove(int i) { node<T> *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 <typename T> void LinkList<T>::traverse(std::ostream &os) const { node<T> *p = head; for (int i = 0;i < size;++i) { os << p->d << " "; p = p->next; } } template <typename T> /** * @brief LinkList<T>::push_front 插入頭部 * @param o */ void LinkList<T>::push_front(const T &o) { node<T> *p = new node<T>(o,tail,head); p->next =head; p->pre = tail; head = p; ++size; } template <typename T> void LinkList<T>::push_tail(const T &o) { add(o); } template <typename T> T LinkList<T>::pop_front() { T t = local(0)->d; remove(0); return t; } template <typename T> T LinkList<T>::pop_tail() { T t = local(size-1)->d; remove(size-1); return t; } #endif