线性表链接实现--双循环链表
2015-05-22 00:00
344 查看
在实现时没有引入两个辅助节点,所以实现时需要考虑特殊情况,比如头和尾插入删除操作时,需要改变指向头和尾的指针。在做迭代器的时候还有麻烦,遍历链表时需要借助量表的长度,不然不能标识结束,我想到的办法是在迭代器中做一些记录工作,比如当前的下标和整个链表的长度。有解决办法的希望指教。
#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
相关文章推荐
- 线性表链接实现--双循环链表
- 数据结构编程笔记六:第二章 线性表 双向循环链表的实现
- 线性表链式存储结构实现 --单向循环链表
- 线性表链式存储结构实现 --双向循环链表
- 线性表实现:顺序表、链表、循环链表、双向循环链表
- C_线性表(ADT)-单向循环链表的表示和实现
- <数据结构> 第二章 线性表之循环链表的代码粗实现
- 2.3线性表的链式表示和实现——2.3.2 循环链表,2.3.3双向链表
- 线性表--双链表实现方式 (JAVA)
- 数据结构_线性表_链表实现
- c语言实现--单向循环链表操作
- 数据结构基础(12) --双向循环链表的设计与实现
- c++实现双向循环链表
- 链表的C语言实现之循环链表及双向链表
- 线性表之链表的实现(二)-静态链表实现
- 线性表链接存储(单链表)
- 双向循环链表的头插、中插、尾插、删除、逆序顺序显示(C++实现)
- 简单数据结构之循环链表(C++实现)
- Java数据结构-线性表之循环链表
- 数据结构_链表实现无限循环的"环"结构/循环队列