线性表链接实现--双循环链表

来源:互联网 发布:磁球魔方淘宝 编辑:程序博客网 时间:2024/04/28 03:37

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

                   

#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


原创粉丝点击