C++--list的模拟实现

35 篇文章 0 订阅

  • list 是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以在前后双向迭代;
  • list 底层是双向链表结构。

1. list节点类

//list实现:双向带头的循环链表
//list节点类
template<class T>
struct ListNode
{
	ListNode(const T& val = T())
		:_pPre(nullptr)
		, _pNext(nullptr)
		, _val(val)
	{}
	ListNode<T>* _pPre;
	ListNode<T>* _pNext;
	T _val;
};

2. list迭代器的实现

list的迭代器实现方式有两种,具体应该根据容器底层数据结构实现:

  1. 原生态指针,如:vector;
  2. 将原生态指针进行封装,因迭代器使用形式与指针完全相同,因此在自定义的类中必须实现一下方法:
    · 指针可以解引用,迭代器的类中必须重载operator*();
    · 指针可以通过->访问其所指向的空间成员,迭代器中必须重载operator->();
    · 指针可以++向后移动,迭代器类中必须重载operator++()与operator(int);
    · 迭代器需要进行是否相等的比较,因此还需要重载operator==()与operator!=()。
//list迭代器实现:自定义类型,封装节点
//list的迭代器类
template<class T, class Ref, class Ptr>
class ListIterator
{
	typedef ListNode<T>* PNode;
	typedef ListIterator<T, Ref, Ptr> Self;
public:
	//封装节点
	PNode _pNode;
	ListIterator(PNode pNode = nullptr)
		:_pNode(pNode)
	{}
	ListIterator(const Self& l)
		:_pNode(l._pNode)
	{}
	//重载 *iterator
	T& operator*()
	{
		return _pNode->_val;
	}
	T* operator->()
	{
		return &_pNode->val;
	}
	Self& operator++()
	{
		_pNode = _pNode->_pNext;
		return *this;
	}
	Self operator++(int)
	{
		Self tmp = *this;
		_pNode = _pNode->_pNext;
		return *this;
	}
	Self& operator--()
	{
		_pNode = _pNode->_pPre;
		return *this;
	}
	Self operator--(int)
	{
		Self tmp = *this;
		_pNode = _pNode->_pPre;
		return *this;
	}
	bool operator!=(const Self& l)
	{
		return _pNode != l._pNode;
	}
	bool operator ==(const Self& l)
	{
		return _pNode == l._pNode;
	}
//private:
	//PNode _pNode;
};

3. list类的实现

3.1 构造函数

3.1.1 无参构造

	//无参构造
	List()
		:_pHead(new Node())
	{
		//循环结构
		_pHead->_pNext = _pHead->_pPre = _pHead;
	}

3.1.2 n个缺省值的构造

	List(int n, const T& value = T())
		:_pHead(new Node())
	{
		_pHead->_pNext = _pHead->_pPre = _pHead;
		for (size_t i = 0; i < n; i++)
		{
			push_back(value);
		}
	}

3.1.3 迭代器区间的构造

	template<class iterator>
	List(iterator first, iterator last)
		:_pHead(new Node())
	{
		_pHead->_pNext = _pHead->_pPre = _pHead;
		while (first != last)
		{
			push_back(*first);
			++first;
		}
	}

3.1.4 拷贝构造

	List(const List<T>& l)
		:_pHead(new Node())
	{
		//循环结构
		_pHead->_pNext = _pHead->_pPre = _pHead;
		for (auto& e : l)
		{
			push_back(e);
		}
	}
	List<T>& operator=(const List<T> l)
	{
		Swap(l);
		return *this;
	}
	void Swap(List<T>& l)
	{
		swap(_pHead, l._pHead);
	}

3.2 析构函数

	//析构
	~List()
	{
		if (_pHead)
		{
			Node* node = _pHead->_pNext;
			while (node != _pHead)
			{
				Node* next = node->_pNext;
				delete node;
				node = next;
			}
			delete _pHead;
			_pHead = nullptr;
		}
	}

3.3 iterator

	//List iterator
	iterator begin()
	{
		return iterator(_pHead->_pNext);
	}
	iterator end()
	{
		return iterator(_pHead);
	}
	const_iterator begin()const
	{
		return const_iterator(_pHead->_pNext);
	}
	const_iterator end()const
	{
		return const_iterator(_pHead);
	}

3.4 capacity

3.4.1 size

	//List Capacity
	size_t size()const
	{
		size_t size = 0;
		Node* p = _pHead->_pNext;
		while (p != _pHead)
		{
			size++;
			p = p->_pNext;
		}
		return size;
	}

3.4.2 empty

	bool empty()const
	{
		return size() == 0;
	}

3.5 access

3.5.1 front

	//List Access
	T& front()
	{
		assert(!empty());
		return _pHead->_pNext->_val;
	}
	const T& front()const
	{
		assert(!empty());
		return _pHead->_pNext->_val;
	}

3.5.2 back

T& back()
	{
		assert(!empty());
		return _pHead->_pPre->_val;
	}
	const T& back()const
	{
		assert(!empty());
		return _pHead->_pPre->_val;
	}

3.6 插入、删除

3.6.1 insert

//在pos位置前插入值尾val的节点
	//不会导致迭代器失效
	void insert(iterator pos, const T& val)
	{
		Node* newNode = new Node(val);
		Node* cur = pos._pNode;
		//curpre newnode cur
		newNode->_pPre = cur->_pPre;
		newNode->_pNext = cur;
		newNode->_pPre->_pNext = newNode;
		cur->_pPre = newNode;
	}

3.6.2 erase

	//删除pos位置的节点,返回该节点的下一个位置
	//迭代器指向的节点释放,迭代器失效
	//更新迭代器
	iterator erase(iterator pos)
	{
		if (pos != end())
		{
			Node* cur = pos._pNode;
			Node* prev = cur->_pPre;
			Node* next = cur->_pNext;
			delete cur;
			prev->_pNext = next;
			next->_pPre = prev;
			return iterator(next);
		}
		return pos;
	}

3.6.3 push

	//List Modify
	//头插
	void push_front(const T& val)
	{
		insert(begin(), val);
	}
	//尾插
	void push_back(const T& val)
	{
		insert(end(), val);
	}

3.6.4 pop

//头删
	void pop_front()
	{
		erase(begin());
	}
	//尾删
	void pop_back()
	{
		erase(--end());
	}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值