【C++】list

1.list的介绍

list的底层的双向链表,在节点中通过指针指向其前一个元素和后一个元素。所以是可以在常数范围内在任意位置进行插入和删除的序列式容器。list和(array,vector,deque)相比list通常在任意位置进行插入、移除元素的执行效率更高。

可参考官方文档:cplusplus.com/reference/list/list/?kw=list

2.list的使用

2.1构造函数

list (size_type n, const value_type& val = value_type()) 构造的list中包含n个值为val的元素

list()                                                                                 构造空的list

list (const list& x)                                                             拷贝构造函数

list (InputIterator first, InputIterator last)                         用[first, last)区间中的元素构造list

    list<int> l1;                         // 构造空的l1
    list<int> l2(6, 0);                 // l2中放6个值为0的元素
    list<int> l3(l2.begin(), l2.end());  // 用l2的[begin(), end())左闭右开的区间构造l3
    list<int> l4(l3);                    // 用l3拷贝构造l4

2.2迭代器iterator

begin + end 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器

rbegin + rend 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的 reverse_iterator,即begin位置

list<int>::iterator it = l1.begin();
    while (it != l1.end())
    {
        cout << *it << " ";
        ++it;
    }       
    cout << endl;


    for (auto& e : l1)
    {
        cout << e << " ";
    }

    cout << endl;

 2.3 capacity

empty 检测list是否为空,是返回true,否则返回false

size 返回list中有效节点的个数

2.4 element access

front 返回list的第一个节点中值的引用

back 返回list的最后一个节点中值的引用

2.5修改

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中的有效元素

void Test()
{
    int array1[] = { 1 , 2 , 3 , 4 , 5 };
    list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));

    // 获取链表中第二个节点
    auto pos = ++L.begin();
    cout << *pos << endl;
    L.insert(pos, 4);
    // 在pos前插入5个值为5的元素
    L.insert(pos, 5, 5);
    // 在pos前插入[v.begin(), v.end)区间中的元素
    vector<int> v{ 7, 8, 9 };
    L.insert(pos, v.begin(), v.end());
    // 删除pos位置上的元素
    L.erase(pos);
    // 删除list中[begin, end)区间中的元素,即删除list中的所有元素
    L.erase(L.begin(), L.end());

}
    // 用数组来构造list
    int array1[] = { 1, 2, 3 };
    list<int> l1(array1, array1 + sizeof(array1) / sizeof(array1[0]));

    // 交换l1和l2中的元素
    list<int> l2;
    l1.swap(l2);

    // 将l2中的元素清空
    l2.clear();
    cout << l2.size() << endl;

2.6 list迭代器失效

list也有迭代器失效的问题

void Test()
{
    list<int> l{ 1,2,3,4,5,6 };
    list<int>::iterator it = l.begin();
    while (it != l.end())
    {
        l.erase(it);// erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给其赋值
        it++;
    }
    
}

以上代码要修改成:

void Test()
{
    list<int> l{ 1,2,3,4,5,6 };
    list<int>::iterator it = l.begin();
    while (it != l.end())
    {
        it = l.erase(it);
       
    }

}

erase会返回迭代器的下一个位置

3.list的模拟实现

namespace crin
{
	template<class T>
	 struct _List_Node
	{
		 _List_Node(const T& x = T())
			 :_data(x)
			 , prev(nullptr)
			 , next(nullptr)
		 {}
		T _data;
		_List_Node* prev;
		_List_Node* next;
	};
	 template<class T,class Ref,class Ptr>
	 struct _List_Iterator
	 {
		 typedef _List_Node<T> Node;
		 typedef _List_Iterator<T,Ref,Ptr> iterator;
		 Node* _Node;

		 _List_Iterator(Node* Node)
			 :_Node(Node)
		 {}
		 bool operator!=(const iterator& it)
		 {
			 return _Node != it._Node;
		 }
		 bool operator==(const iterator& it)
		 {
			 return _Node == it._Node;
		 }


		 Ref operator*()
		 {
			 return _Node->_data;
		 }
		 Ptr operator->()
		 {
			 return &_Node->_data;
		 }

		 iterator& operator++()
		 {
			 _Node = _Node->next;
			 return *this;
		 }

		 iterator& operator--()
		 {
			 _Node = _Node->prev;
			 return *this;
		 }

		 iterator operator++(int)
		 {
			iterator tmp(*this);
			 _Node = _Node->next;
			 return tmp;
		 }

		 iterator operator--(int)
		 {
			 iterator tmp(*this);
			 _Node = _Node->prev;
			 return tmp;
		 }

	 };


	 template<class T>
	 class List
	 {
		 typedef _List_Node<T> Node;
		
	 public:
		 typedef _List_Iterator<T,T&,T*> iterator;
		 typedef _List_Iterator<T, const T&, const T*> const_iterator;
		 iterator begin()
		 {
			 return _head->next;
		 }
		 iterator end()
		 {
			 return _head;
		 }
		 iterator insert(iterator pos,const T& x)
		 {
			 Node* next = pos._Node;
			 Node* newnode = new Node(x);
			 Node* prev = next->prev;
			 newnode->next = next;
			 newnode->prev = prev;
			 prev->next = newnode;
			 next->prev = newnode;
			 _size++;
			 return iterator(newnode);
		 }

		 List()
		 {
			 empty_init();
		 }
		 List( List<T>& lt)
		 {
			 empty_init();
			 for (auto d : lt)
			 {
				 push_back(d);
			 }
		 }

		 void swap(List<T>& lt)
		 {
			 std::swap(_head, lt._head);
			 std::swap(_size, lt._size);
		 }
		 List<T>& operator=(List<T> lt)
		 {
			 swap(lt);
			 return *this;
		 }


		 void clear()
		 {
			 iterator it = begin();
			 while (it != end())
			 {
				 it = erase(it);
			 }
		 }
		 
		 ~List()
		 {
			 clear();
			 delete _head;
			 _head = nullptr;
		 }


		 void push_back(const T& x)
		 {
			 /*Node* newnode = new Node(x);
			 Node* next = _head->prev;
			 newnode->next = _head;
			 newnode->prev = next;
			 _head->prev = newnode;
			 next->next = newnode;
			 _size++;*/
			 insert(end(), x);

		 }
		 void push_front(const T& x)
		 {
			 insert(begin(), x);
		 }
		
		 iterator erase(iterator pos)
		 {
			 Node* prev = pos._Node->prev;
			 Node* next = pos._Node->next;
			 prev->next = next;
			 next->prev = prev;
			 delete pos._Node;
			 _size--;
			 return iterator(next);
		 }

		 void pop_back(iterator pos)
		 {
			 erase(--end());
		 }
		 void pop_front(iterator pos)
		 {
			 erase(begin());
		 }
		 size_t size()
		 {
			 return _size;
		 }





	 private:
		 void empty_init()
		 {
			 _head = new Node;
			 _head->next = _head;
			 _head->prev = _head;
			 _size = 0;
		 }
		 Node* _head;
		 size_t _size;
	 };
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值