C++Helper--实现迭代器iterator版本的双向循环链表list(增、删、改、查、排序、去重等)

本文介绍了如何实现一个带有迭代器功能的双向循环链表,包括增删改查、排序和去重等操作。链表设计参考std::list,通过内部的双向链表存储数据,单向链表分配内存,以提高性能。源码可在GitHub找到。
摘要由CSDN通过智能技术生成

  实现一个单链表,或是双向链表,是我们学习、面试,和工作中经常遇到的问题,于是,我们这里动手实现一个双向循环链表。

  在上一篇,我们在原有的std::list基础上,扩展了增删改查等一系列接口。为适用于普通算法,这里实现了迭代器的功能。为防止重复申请和释放操作,内部保留一个已分配的空间,以提高性能。

  本文源码见【完整代码】章节,或GitHub:https://github.com/deargo/cpphelper

实现介绍

  链表的接口完全参考std::list,但为了实际使用,需要加以丰富,比如新增、查询、删除、检索、排序、去重等。

  链表可迭代器访问,支持前向和反向迭代器,以便于适用于算法函数。

  为提高链表性能,减少频繁的新增和删除元素,内部使用两个链式结构。其中用于存储数据的链表,为双向链表用于分配内存的链表为单向链表

  两个链表中的每个元素,都继承自NodeBase,他包含前驱指针prev,和后继指针next

  存储链表元素Node结点,他的唯一成员为存储的数据对象。但比较特殊都是,其哨兵结点为NodeBae类型保留链表为提高性能,存储为NodeBase对象,且作为单向列表取值和新增都在头结点操作

  内部链表结构见下图:

完整代码

#pragma once

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

#include <list>
#include <vector>
#include <set>
#include <algorithm>
#include <functional>
#include <assert.h>

namespace CppHelper
{

template<typename Type>
class CLinkList
{
private:
    //定义双链表的前驱结点和后继节点
    struct NodeBase
    {
        NodeBase* next;
        NodeBase* prev;
        NodeBase() : next(nullptr), prev(nullptr) {}
    };

    //仅定义数据成员,将数据操作和链表操作分离
    struct Node : public NodeBase
    {
        Type data;
    };

private:

    //双向迭代器前置声明
    class Iterator;

    //const双向迭代器
    class ConstIterator
    {
        friend class CLinkList;

        const NodeBase* node = nullptr;
        const NodeBase* guard = nullptr;

        ConstIterator(const NodeBase *pGuard, const NodeBase *pNode) : guard(pGuard),node(pNode) {}

    public:
        typedef ptrdiff_t                       difference_type;
        typedef std::bidirectional_iterator_tag iterator_category;
        typedef Type                            value_type;
        typedef const Type*                     pointer;
        typedef const Type&                     reference;

    public:
        ConstIterator(const Iterator& it) : guard(it.guard),node(it.node) {}

        reference operator*() const { assert(guard!=node); return static_cast<const Node*>(node)->data; }

        pointer operator->() const { assert(guard!=node); return &static_cast<const Node*>(node)->data; }

        ConstIterator& operator++() { node = node->next; return *this; }
        ConstIterator operator++(int) { const ConstIterator temp = *this; node = node->next; return temp; }

        ConstIterator& operator--() { node = node->prev; return *this; }
        ConstIterator operator--(int) { const ConstIterator temp = *this; node = node->prev; return temp; }

        ConstIterator operator+(int distance) const
        {
            ConstIterator temp = *this;
            while(temp.node && distance--) temp.node = temp.node->next;
            return temp;
        }

        ConstIterator operator-(int distance) const
        {
            ConstIterator temp = *this;
            while(temp.node->prev && distance--) temp.node = temp.node->prev;
            return temp;
        }

        ConstIterator& operator+=(int distance) { while(node && distance--) node = node->next; return *this; }
        ConstIterator& operator-=(int distance) { while(node->prev && distance--) node = node->prev;return *this;}

        bool operator==(const ConstIterator& other) const { return node == other.node; }
        bool operator!=(const ConstIterator& other) const { return node != other.node; }

        bool valid() const { return guard!=node;}
    };

    //双向迭代器
    class Iterator
    {
        friend class CLinkList;

        NodeBase* node = nullptr;
        const NodeBase* guard = nullptr;

        Iterator(NodeBase* pGuard, NodeBase* pNode) : guard(pGuard),node(pNode){}

    public:
        typedef ptrdiff_t                        difference_type;
        typedef std::bidirectional_iterator_tag  iterator_category;
        typedef Type                             value_type;
        typedef Type*                            pointer;
        typedef const Type*                      const_pointer;
        typedef Type&                            reference;
        typedef const Type&                      const_reference;

    public:

        reference operator*() { assert(guard!=node); return static_cast<Node*>(node)->data; }
        const_reference operator*() const  { assert(guard!=node); return static_cast<Node*>(node)->data; }

        pointer operator->() { assert(guard!=node); return &static_cast<Node*>(node)->data; }
        const_pointer operator->() const { assert(guard!=node); return &static_cast<Node*>(node)->data; }

        Iterator& operator++() { node = node->next; return *this; }
        Iterator operator++(int) { Iterator temp = *this; node = node->next; return temp; }

        Iterator& operator--() { node = node->prev; return *this; }
        Iterator operator--(int) { Iterator temp = *this; node = node->prev; return temp; }

        Iterator operator+(int distance)
        {
            Iterator temp = *this;
            while(temp.node && distance--) temp.node = temp.node->next;
            return temp;
        }
        ConstIterator operator+(int distance) const
        {
            Iterator temp = *this;
            while(temp.node && distance--) temp.node = temp.node->next;
            return ConstIterator(temp.node);
        }

        Iterator operator-(unsigned int distance)
        {
            Iterator temp = *this;
            while(temp.node->prev && distance--) temp.node = temp.node->prev;
            return temp;
        }
        ConstIterator operator-(unsigned int distance) const
        {
            Iterator temp = *this;
            while(temp.node->prev && distance--) temp.node = temp.node->prev;
            return ConstIterator(temp.node);
        }

        Iterator& operator+=(unsigned int distance) { while(node && distance--) node = node->next; return *this; }
        Iterator& operator-=(unsigned int distance) { while(node->prev && distance--) node = node->prev; return *this; }

        bool operator==(const Iterator& other) const { return node == other.node; }
        bool operator!=(const Iterator& other) const { return node != other.node; }

        bool valid() const{ return guard!=node;}
    };

public:
    typedef Type                                  value_type;
    typedef Typ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值