博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线性表链接实现--双循环链表
阅读量:6671 次
发布时间:2019-06-25

本文共 4435 字,大约阅读时间需要 14 分钟。

hot3.png

                    在实现时没有引入两个辅助节点,所以实现时需要考虑特殊情况,比如头和尾插入删除操作时,需要改变指向头和尾的指针。在做迭代器的时候还有麻烦,遍历链表时需要借助量表的长度,不然不能标识结束,我想到的办法是在迭代器中做一些记录工作,比如当前的下标和整个链表的长度。有解决办法的希望指教。

                   

#ifndef LINKLIST_H#define LINKLIST_H#include "list.hpp"template 
struct 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

转载于:https://my.oschina.net/u/854744/blog/418519

你可能感兴趣的文章