学习->C++篇九:list

目录

list简介:

构造函数:

常用成员函数:

 list的简易实现:

简易测试:


list简介:

list是一个顺序容器,允许在任意位置以O(1)的时间复杂度插入或删除(比vector,deque等的效率都高)。list的底层结构是一个带头节点的双向循环链表,故其迭代器类型是双向迭代器。list的迭代器近似于指针,只有在删除元素时迭代器才会失效(只有删除的元素的迭代器失效)。

构造函数:

default (1)
explicit list (const allocator_type& alloc = allocator_type());
fill (2)
explicit list (size_type n, const value_type& val = value_type(),
                const allocator_type& alloc = allocator_type());
range (3)
template <class InputIterator>
  list (InputIterator first, InputIterator last,
         const allocator_type& alloc = allocator_type());
copy (4)
list (const list& x);

(1)默认构造函数:构造出一个只有头结点的双向循环链表。

(2)用n个val构造链表

(3)用两个任意类型的迭代器区间去构造链表

(4)拷贝构造已有的链表

常用成员函数:

empty : 检测 list 是否为空,是返回 true ,否则返回 false
size : 返回 list 中存储数据的个数
front : 返回 list 的第一个节点存储的数据的引用
back : 返回 list 的最后一个节点存储的数据的引用
push_front : list 首元素前插入值为 val 的元素
pop_front : 删除 list 中第一个元素
push_back : list 尾部插入值为 val 的元素
pop_back : 删除 list 中最后一个元素
insert : list的(迭代器) position 位置中插入值为 val 的元素
(返回新插入元素的迭代器)
erase : 删除 list的 (迭代器)position 位置的元素
(返回删除元素的后一个元素的迭代器)
swap : 交换两个 list 中的数据(交换后迭代器不会失效)
clear : 清空 list 中的所有数据

 list的简易实现:

#pragma once

template <class T>
struct list_node
{
	list_node<T>* _prev;
	list_node<T>* _next;
	T _data;

	list_node(const T& val = T())
		:_prev(nullptr)
		,_next(nullptr)
		,_data(val)
	{}
};

template <class T, class Ref, class Ptr>
struct list_iterator
{
	typedef list_node<T> Node;//简化一下名字
	typedef list_iterator<T, Ref, Ptr> Self;//简化一下名字
	
	Node* _node;//迭代器里面就一个 节点指针

	list_iterator(Node*node)
		:_node(node)
	{}

	Ref operator*() { return _node->_data; }
	Ptr operator->() { return &(operator*()); }
	Self operator++()
	{
		_node = _node->_next;
		return *this;
	}
	Self operator++(int)
	{
		Self tmp(_node);
		_node = _node->_next;
		return tmp;
	}
	Self operator--()
	{
		_node = _node->_prev;
		return *this;
	}
	Self operator--(int)
	{
		Self tmp(_node);
		_node = _node->_prev;
		return tmp;
	}

	bool operator!=(const Self& it)const { return it._node != _node; }
	bool operator==(const Self& it)const { return it._node == _node; }
};

//实现反向迭代器,也适用于其他的容器
template <class Iterator,class Ref,class Ptr>
struct Reverse_iterator
{
	Iterator _it;
	typedef Reverse_iterator<Iterator, Ref, Ptr> Self;
	Reverse_iterator(Iterator it)
		:_it(it)
	{}
	Ref operator*()
	{
		Iterator tmp = _it;
		return *(--tmp);
		//反向迭代器可以从end()开始
	}
	Ptr operator->()
	{
		return &(operator*());
	}
	Self operator++()
	{
		--_it;
		return *this;
	}
	Self operator++(int)
	{
		Iterator tmp = _it;
		--_it;
		return tmp;
	}
	Self operator--()
	{
		++_it;
		return *this;
	}
	Self operator--(int)
	{
		Iterator tmp = _it;
		++_it;
		return tmp;
	}
	bool operator!=(const Self& it)const { return it._it != _it; }
	bool operator==(const Self& it)const { return it._it == _it; }
};

template <class T>
class list
{
	typedef list_node<T> Node;
public:
	//正向迭代器与反向迭代器(各两个版本,const对象和普通对象的)
	typedef list_iterator<T, T&, T*> iterator;
	typedef list_iterator<T,const T&,const T*> const_iterator;
	typedef Reverse_iterator<iterator, T&, T*>reverse_iterator;
	typedef Reverse_iterator<const_iterator, const T&, const T*>const_reverse_iterator;

	iterator begin() { return iterator(_head->_next); }
	iterator end() { return iterator(_head); }
	const_iterator begin() const{ return const_iterator(_head->_next); }
	const_iterator end() const { return const_iterator(_head); }
	reverse_iterator rbegin() { return reverse_iterator(end()); }
	reverse_iterator rend() { return reverse_iterator(begin()); }
	const_reverse_iterator rbegin()const { return const_reverse_iterator(end()); }
	const_reverse_iterator rend()const { return const_reverse_iterator(begin()); }

	//构造函数
	list() { empty_init(); }
	
	template <class InputIterator>
	list(InputIterator first,InputIterator last)
	{
		empty_init();
		while (first != last)
			push_back(*first++);
	}

	void swap(list<T>&lt)
	{
		std::swap(_head, lt._head);
		std::swap(_size, lt._size);
	}

	list(list<T>& lt)
	{
		empty_init();
		list<T>tmp(lt.begin(), lt.end());
		swap(tmp);
	}

	list<T>& operator=(list<T> lt)//简便的现代写法
	{
		swap(lt);
		return *this;
	}

	~list() { clear(); delete _head; }
	
	void clear()
	{
		iterator it = begin();
		while (it != end())
			it = erase(it);//避免迭代器失效
	}

	void push_back(const T& val) { insert(end(), val); }
	void push_front(const T& val) { insert(begin(), val); }
	void pop_back() { erase(--end()); }
	void pop_front() { erase(begin()); }

	iterator erase(iterator it)
	{
		Node* cur = it._node;
		Node* next = cur->_next;
		Node* prev = cur->_prev;

		prev->_next = next;
		next->_prev = prev;
		delete cur;

		--_size;
		return iterator(next);
	}
	
	iterator insert(iterator it,const T&val)
	{
		Node* newnode = new Node(val);
		Node* cur = it._node;
		Node* prev = cur->_prev;

		newnode->_next = cur;
		cur->_prev = newnode;
		newnode->_prev = prev;
		prev->_next = newnode;

		++_size;
		return iterator(newnode);
	}

	size_t size()const { return _size; }
	bool empty()const { return _size == 0; }
private:
	void empty_init()
	{
		_head = new Node;
		_head->_prev = _head;
		_head->_next = _head;
		_size = 0;
	}
private:
	Node* _head;
	size_t _size;
};

简易测试:

void test_mylist()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	for (auto e : lt)
		cout << e << " ";
	cout<< endl;

	list<int>::reverse_iterator it = lt.rbegin();
	while (it != lt.rend())
		cout << *it++ << " ";
	cout << endl;

	auto it0 = lt.begin();
	while (it0 != lt.end())
	{
		if (*it0 % 2 == 0)
			lt.insert(it0, *it0);
		++it0;
	}

	for (auto e : lt)
		cout << e << " ";
	cout << endl;

    cout << "size==" << lt.size() << endl;
}
int main() 
{
	test_mylist();
	return 0;
}

输出:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值