【C++】模拟实现List

一. 定义和成员变量

// List的节点类
template<class T>
struct ListNode
{
    ListNode(const T& val= T())
        :_val(val)
        ,_prev(this)	//指向之后都要更改的
        ,_next(this)	
    {}
    
    ListNode<T>* _prev;	//指向前一个节点
    ListNode<T>* _next;	//指向后一个节点
    T _val;			//节点数据
};

template<class T>
class list
{
    typedef ListNode<T> Node;
    typedef Node* PNode;
    
private:
	void CreateHead()	//每个构造函数都需要创造哨兵节点, 所以单独创建一个函数调用
	{
	    _pHead = new Node;
	}
	
	PNode _pHead = nullptr;	//哨兵节点
};

二. 迭代器

由于 List 的数据并不像 Vector, String 一样连续存放的, 为了统一迭代器的使用方式, 所以 List 的迭代器是一个类, 操作符在类中重载的.

//List的迭代器类
template<class T, class Ref, class Ptr>
class ListIterator
{
    typedef ListNode<T>* PNode;
    typedef ListIterator<T, Ref, Ptr> Self;
public:
	//使用节点指针或者无参初始化迭代器
    ListIterator(PNode pNode = nullptr)
        :_pNode(pNode)
    {}
	
    Ref operator*()	
    {
        return _pNode->_val;
    }

    Ptr operator->()
    {
        return &(_pNode->_val);
    }

    Self& operator++()
    {
        _pNode = _pNode->_next;
        return *this;
    }

    Self operator++(int)
    {
        Self tmp(*this);
        _pNode = _pNode->_next;
        return tmp;
    }

    Self& operator--()
    {
        _pNode = _pNode->_prev;
        return *this;
    }

    Self operator--(int)
    {
        Self tmp(*this);
        _pNode = _pNode->_prev;
        return tmp;
    }

    bool operator!=(const Self& l)
    {
        return _pNode != l._pNode;
    }

    bool operator==(const Self& l)
    {
        return _pNode == l._pNode;
    }

    PNode _pNode;	//迭代器类的成员, 保存节点的指针
};

为了统一, 在 List 类中 typedef 迭代器

//list类
template<class T>
class list
{
    typedef ListNode<T> Node;
    typedef Node* PNode;
public:
    typedef ListIterator<T, T&, T*> iterator;
    typedef ListIterator<T, const T&, const T*> const_iterator;
    //typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
    ...
      List Iterator
     iterator begin()
     {
         return _pHead->_next;
     }
     iterator end()
     {
         return _pHead;
     }
     
     const_iterator begin() const
     {
         return _pHead->_next;
     }
     const_iterator end() const
     {
         return _pHead;
     }
     ...
};

三. 默认成员函数

1. 构造函数

//无参构造函数, 只需创造哨兵节点即可
list()
{
    CreateHead();
}

//迭代器区间构造函数, 和 vector 一样, 只需将每个数据插入即可
template <class Iterator>
list(Iterator first, Iterator last)
{
    CreateHead();
    while (first != last)
    {
        push_back(*first);	//push_back() 函数在后面
        ++first;
    }
}

2. 析构函数

~list()
{
	//手动释放空间
    /*if (_pHead)
    {
        PNode cur = _pHead->_next;
        while (cur != _pHead)
        {
            cur = cur->_next;
            delete (cur->_prev);
        }
        delete _pHead;
        _pHead = nullptr;
    }*/
    
    clear();		//调用 clear() 函数释放空间即可
    delete _pHead;	//释放哨兵节点
    _pHead = nullptr;//置空
}

3. 拷贝构造

//拷贝构造 
list(const list<T>& l)
{
    list<T> tmp(l.begin(), l.end());//利用迭代器区间初始化 tmp 对象
    swap(tmp);						//使用内置 swap()函数(在下面) 交换即可
}

4. 赋值重载

//赋值重载	复用拷贝构造和 swap() 函数即可
list<T>& operator=(const list<T> l)		
{
    swap(l);
    return *this;
}

四. 其他成员函数

1. 内置 swap

void swap(list<T>& l)
{
    std::swap(_pHead, l._pHead);	//交换哨兵节点指针即可
}

2. insert()

// 在pos位置前插入节点, 返回新插入的节点
iterator insert(iterator pos, const T& val)
{
    PNode new_node = new Node(val);	//新节点

    PNode cur = pos._pNode;		//当前节点
    PNode prev = cur->_prev;	//前一个节点
	
	//插入节点
    prev->_next = new_node;			
    new_node->_prev = prev;
    new_node->_next = cur;
    cur->_prev = new_node;
    
    return new_node;
}

4. push_back()

void push_back(const T& val)
{ 
	insert(end(), val);		//调用 insert() 即可
}

5. erase()

//删除pos位置的节点, 返回该节点的下一个位置
iterator erase(iterator pos)
{
    PNode cur = pos._pNode;		//当前节点
    PNode prev = cur->_prev;	//前一个节点
    PNode next = cur->_next;	//后一个节点
	
	//前后相连
    prev->_next = next;
    next->_prev = prev;

    delete cur;					//释放当前节点空间
    return next;				//返回后一个节点
}

6. pop_back()

void pop_back() 
{ 
	erase(--end()); 		//调用 erase() 即可
}

7. clear()

void clear()
{
    iterator it = begin();
    while (it != end())		//释放除哨兵节点以外的所有节点
        it = erase(it);
}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值