美文网首页
双线链表

双线链表

作者: 海阔天空的博客 | 来源:发表于2021-11-27 00:06 被阅读0次

双向链表的特点:
1、以节点为单位,每个节点有上个节点指针和下个节点指针
2、至少包含头节点和尾节点
3、添加节点时先改变新增节点的上下节点指针指向,后修改前后节点的指针指向为当前节点
4、删除节点时修改当前节点的前后节点指向,然后删除当前节点
5、迭代器用来封装节点数据,并提供了操作符的能力,如*,++,==,!=
6、列表的操作有:取头,取尾,删头,删尾,删指定位置,加头,加尾,加指定位置

template <class Object>
class List
{
private:
    struct Node
    {
        Object data;
        Node *prev;
        Node *next;
 
        Node(const Object &d = Object(), Node *p = NULL, Node *n = NULL)
            : data(d), prev(p), next(n)
        {
 
        }
    };
 
public:
    class const_iterator
    {
    public:
        const_iterator() : current(NULL)
        {
 
        }
 
        const Object &operator* () const
        {
            return retrieve();
        }
 
        const_iterator & operator++ ()
        {
            current = current->next;
            return *this;
        }
 
        const_iterator operator++ (int)
        {
            const_iterator old = *this;
            ++(*this);
            return old;
        }
 
        bool operator == (const const_iterator &rhs) const
        {
            return current == rhs.current;
        }
 
        bool operator != (const const_iterator &rhs) const
        {
            return !(*this == rhs);
        }
 
    protected:
        Node *current;
        Object &retrieve() const
        {
            return current->data;
        }
        const_iterator(Node *p) : current(p)
        {
 
        }
 
        friend class List < Object >;
    };
 
    class iterator : public const_iterator
    {
    public:
        iterator()
        {
 
        }
 
        Object & operator* ()
        {
            return retrieve();
        }
 
        iterator &operator++()
        {
            current = current->next;
            return *this;
        }
 
        iterator operator++ (int)
        {
            iterator old = *this;
            ++(*this);
            return old;
        }
 
    protected:
        iterator(Node *p) : const_iterator(p)
        {
 
        }
 
        friend class List < Object >;
    };
 
public:
    List()
    {
        init();
    }
    ~List()
    {
        clear();
        delete head;
        delete tail;
    }
    List(const List &rhs)
    {
        init();
        *this = rhs;
    }
 
    const List &operator = (const List &rhs)
    {
        if (this == &rhs)
        {
            return *this;
        }
        clear();
        for (const_iterator itr = rhs.begin(); itr != rhs.end(); ++itr)
        {
            push_back(*itr);
        }
 
        return *this;
    }
 
    iterator begin()
    {
        return iterator(head->next);
    }
 
    const_iterator begin() const
    {
        return const_iterator(head->next);
    }
 
    iterator end()
    {
        return iterator(tail);
    }
 
    const_iterator end() const
    {
        return const_iterator(tail);
    }
 
    int size() const
    {
        return theSize;
    }
    bool empty() const
    {
        return size() == 0;
    }
 
    void clear()
    {
        while (!empty())
            pop_front();
    }
 
    Object &front()
    {
        return *begin();
    }
 
    const Object & front() const
    {
        return *begin();
    }
    Object &back()
    {
        return *--end();
    }
    const Object &back() const
    {
        return *--end();
    }
    void push_front(const Object &x)
    {
        insert(begin(), x);
    }
    void push_back(const Object &x)
    {
        insert(end(), x);
    }
    void pop_front()
    {
        erase(begin());
    }
    void pop_back()
    {
        erase(--end());
    }
 
    iterator insert(iterator itr, const Object &x)
    {
        Node *p = itr.current;
        theSize++;
        return iterator(p->prev = p->prev->next = new Node(x, p->prev, p));
    }
    iterator erase(iterator itr)
    {
        Node *p = itr.current;
        iterator retVal(p->next);
        p->prev->next = p->next;
        p->next->prev = p->prev;
        delete p;
        theSize--;
 
        return retVal;
    }
 
    iterator erase(iterator start, iterator end)
    {
        for (iterator itr = start; itr != end;)
        {
            itr = erase(itr);
        }
 
        return end;
    }
 
private:
    int theSize;
    Node *head;
    Node *tail;
    void init()
    {
        theSize = 0;
        head = new Node;
        tail = new Node;
        head->next = tail;
        tail->prev = head;
    }
};
 
int main()
{
    List<int> nList;
    nList.push_back(1);
    nList.push_back(2);
    nList.push_back(3);
    nList.push_back(4);
    for (List<int>::const_iterator itr = nList.begin(); itr != nList.end(); itr++)
    {
        LOG_INFO("itr vaule:" << *itr);
    }
 
    //
    for (List<int>::iterator itr = nList.begin(); itr != nList.end(); )
    {
        nList.erase(itr++);
    }
 
    LOG_INFO("List size:" << nList.size());
    reutrn 0;
}

本文摘录于海阔天空的博客,作者: zjg555543,发布时间: 2015-06-12

相关文章

  • 双线链表

    双向链表的特点:1、以节点为单位,每个节点有上个节点指针和下个节点指针2、至少包含头节点和尾节点3、添加节点时先改...

  • Golang "container/list" 包双向链表实现分

    今天发现一个开发中很少使用的自带包 container/list,这个包实现了双线链表的数据结构。跟 Slice ...

  • 一文搞定双线性化(p=2或3)附Maple代码

    正向Hirota双线性化(p=2) 推广的双线性化(p=3) 逆向双线性化 #正向双线性化restart:with...

  • 高等代数理论基础72:对称双线性函数

    对称双线性函数 对称双线性函数 定义:是线性空间V上的一个双线性函数,若,有,则称为对称双线性函数 若,有,则称为...

  • 双线

    我是一个双线人。 这是从我写小说《寒风》开始的。 最后的白昼逝去,是无尽的极夜;最终的光明消散,是无边...

  • 双线虚拟主机为何那么火?优势在哪?

    在说优势之前先简单科普一下什么是双线虚拟主机,双线虚拟主机又称为智能双线虚拟主机和智能双线网站空间,它能解决国内南...

  • 小程序的双线程模型

    官方文档给出的双线程模型: 小程序的宿主环境 微信客户端提供双线程去执行wxml,wxss,js文件。 双线程模型...

  • 名片活动行,数字化双线营销SaaS创导者

    名片活动行是中国双线营销型SaaS创导者,致力于企业线上线下互联,双线营销,双线推广。将传统企业,展览会,商务活动...

  • G口双线服务器需要多少钱?服务器是什么配置?

    G口双线服务器需要多少钱?服务器是什么配置? G口双线都比较贵,不是硬需要可以考虑单线电信 衡阳双线百兆 40G ...

  • 双线离

    窗外的雨越下越大,伴随着吵闹不停的雷声。林柔没有注意到外面自然界的恶劣天气,她现在只觉得自己的胸中有一团火在烧,仿...

网友评论

      本文标题:双线链表

      本文链接:https://www.haomeiwen.com/subject/adtgoltx.html